學習SpringCloud Hystrix帶你從0到1

1、什麼是災難性的雪崩效應

1.出現雪崩現象的過程

正常狀況下請求通過多個服務傳到服務T,服務T進行處理並逐級返回。php

當服務B接收到了大量的請求時,最終處理服務的服務T會受到壓力,致使服務崩掉。java

由於服務T最早癱瘓,請求就會積壓在服務U,當壓力過大時各級系統都會崩掉,這樣就令這條線路的服務所有不可用了。web

一個線路的癱瘓也會影響到其餘線路,這樣整個系統就會崩掉了redis

2.形成雪崩的緣由

  • 服務提供者不可用(硬件故障、程序bug、緩存擊穿、用戶大量請求)
  • 重試加大流量(用戶重試、代碼邏輯重試)
  • 服務調用者不可用(同步等待形成的資源耗盡)

最終的結果就是一個服務不可用,連帶着多個服務都不可用,最終致使系統全面癱瘓。spring

2、如何解決災難性雪崩效應

  • 降級apache

    超時降級、資源不足時(線程或信號量)降級,降級後能夠配合降級接口返回託底數據後端

    實現一個fallback方法,當請求後端服務出現異常的時候,可使用fallback方法返回值。緩存

  • 隔離(線程池隔離和信號量隔離)服務器

    限制調用分佈式服務的資源使用,某一個調用的服務出現問題不會影響其餘服務調用。網絡

  • 熔斷

    當失敗率(網絡故障、超時形成的失敗率)達到閾值自動觸發降級,熔斷器觸發的快速失敗會進行快速恢復

  • 緩存

    提供了請求緩存

  • 請求合併

    提供請求合併

1.降級

​ 對服務作降級處理

1.1 建立項目
1.2 添加座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
複製代碼
1.3 修改配置文件
spring.application.name=eureka-consumer-ribbon-hystrix
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
複製代碼
1.4 修改啓動類,開啓熔斷器
//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
複製代碼
1.5 在項目中添加Product實體類
1.6 修改ProductService
@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:負載均衡器

    //開啓服務降級處理,指定返回託底數據的方法
    @HystrixCommand(fallbackMethod = "fallback")
    public List<Product> getUsers(){

        //選擇調用的服務的名稱
            //ServiceInstance:封裝了服務的基本信息,如:ip、端口號
        ServiceInstance si = loadBalancerClient.choose("ego-product-provider");
        //拼接訪問服務的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9001/user/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        //ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }

    //返回託底數據的方法
    public List<Product> fallback(){
        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }
}
複製代碼
1.7 如下四種狀況將觸發getFallback調用
  • 方法拋出非 HystrixBadRequestException 異常
  • 方法調用超時
  • 熔斷器開啓攔截調用
  • 線程池隊列信號量是否跑滿

2.請求緩存

​ Hystrix爲了下降訪問服務的頻率,支持將一個請求與返回結果作緩存處理,若是再次請求的url沒有變化,那麼hystrix不會請求服務,而是直接從緩存中將結果返回,這樣能夠大大下降訪問服務的壓力。

​ Hystrix自帶緩存,有如下兩個缺點

​ 1.是一個本地緩存,在集羣狀況下緩存是同步的。

​ 2.不支持第三方緩存容器。如:Redis、Memcache

​ 解決:可使用spring的緩存

2.1 安裝Redis
2.2 建立項目
2.3 添加座標
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
複製代碼
2.4 修改配置文件
spring.application.name=eureka-consumer-ribbon-cache
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

#Redis
spring.redis.database=0
#redis的服務器地址
spring.redis.host=192.168.234.129
#redis端口號
spring.redis.port=6379
#最大鏈接數
spring.redis.pool.max-active=100
#最大等待時間
spring.redis.pool.max-wait=3000
#最大空閒鏈接數
spring.redis.pool.max-idle=200
#最小空閒鏈接數
spring.redis.pool.min-idle=50
#鏈接超時時間
spring.redis.pool.timeout=600
複製代碼
2.5 修改啓動類,開啓緩存
@EnableCaching
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}
複製代碼
2.6 修改ProductService
@Service
//爲緩存數據設置統一前綴
@CacheConfig(cacheNames = {"com.luyi.ego.product"})
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:負載均衡器

    //開啓服務降級處理,指定返回託底數據的方法
    @HystrixCommand(fallbackMethod = "fallback")
    public List<Product> getUsers(){

        //選擇調用的服務的名稱
            //ServiceInstance:封裝了服務的基本信息,如:ip、端口號
        ServiceInstance si = loadBalancerClient.choose("ego-product-provider");
        //拼接訪問服務的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9001/user/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        //ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }

    //返回託底數據的方法
    public List<Product> fallback(){
        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }

    //根據id查詢商品
    @Cacheable(key = "'product' + #id")  //添加id爲後綴生成key
    public Product getProductById(Integer id){
        System.out.println("============Get===========" + id);
        return new Product(id, "新的商品");
    }

    //根據id刪除商品
    @CacheEvict(key = "'product' + #id")
    public void delProductById(Integer id){
        System.out.println("============Del===========" + id);
    }
}
複製代碼
2.7 修改ProductController
@RestController
public class ProductController {

    @Autowired
    private ProductService userService;

    @RequestMapping("/consumer")
    public List<Product> getUsers(){
        return userService.getUsers();
    }

    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public Product get(Integer id){
        return userService.getProductById(id);
    }

    @RequestMapping(value = "del", method = RequestMethod.GET)
    public void del(Integer id){
        userService.delProductById(id);
    }
}

複製代碼

3.請求合併

3.1 沒合併的請求與合併的請求

3.2 什麼狀況下使用請求合併

​ 在微服務架構中會拆分紅多個小的模塊,各個模塊之間進行調用是須要通訊的,可是在併發量大的狀況下會令大量線程處於等待狀態,這就會增長響應時間,因此可使用請求合併將屢次請求合併爲一次請求。

3.3 請求合併的缺點

​ 在設置了請求合併之後,原本一次請求只須要5ms就搞定了,可是使用了請求合併後可能還須要再等待10ms,看看還有沒有其餘請求一塊兒,這樣一次請求就從5ms增長到了15ms。不過若是咱們發起的命令原本就是一個高延遲的命令,那麼這個時候就可使用請求合併了,由於這個時候時間窗的時間消耗就顯得微不足道了。高併發也是請求合併的重要場景

3.4 建立項目
3.5 修改pom文件,添加hystrix座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

複製代碼
3.6 修改配置文件
spring.application.name=eureka-consumer-ribbon-batch
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

複製代碼
3.7 修改ProductService
@Service
public class ProductService {

    //利用 hystrix 合併請求
    @HystrixCollapser(batchMethod = "batchProduct", scope =
            com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
            collapserProperties = {
                    //請求時間間隔在 20ms 以內的請求會被合併爲一個請求,默認爲 10ms
                    @HystrixProperty(name =
                            "timerDelayInMilliseconds", value = "20"),
                    //設置觸發批處理執行以前,在批處理中容許的最大請求數。
                    @HystrixProperty(name = "maxRequestsInBatch",
                            value = "200"),
            })
    //Consumer的Controller調用的方法,該方法返回值必須爲Future類型
    public Future<Product> getProduct(Integer id) {
        System.out.println("==============" + id + "============");
        return null;
    }

    //調用Provider服務的方法(假設)
    @HystrixCommand
    public List<Product> batchProduct(List<Integer> ids) {
        for (Integer id : ids) {
            System.out.println(id);
        }
        //假設是調用provider服務後返回的list
        List<Product> list = new ArrayList<>();
        list.add(new Product(1, "電視"));
        list.add(new Product(2, "電腦"));
        list.add(new Product(3, "冰箱"));
        list.add(new Product(4, "手電筒"));
        list.add(new Product(100, "list....."));
        System.out.println("ddddddddddd");
        return list;
    }
}

複製代碼
3.8 修改Controller
@RestController
public class ProductController {

    @Autowired
    private ProductService userService;

    @RequestMapping("/consumer")
    public void getUsers() throws ExecutionException, InterruptedException {
        Future<Product> p1 = userService.getProduct(1);
        Future<Product> p2 = userService.getProduct(2);
        Future<Product> p3 = userService.getProduct(3);

        System.out.println(p1.get().toString());
        System.out.println(p2.get().toString());
        System.out.println(p3.get().toString());
    }
}

複製代碼
3.9 請求合併參數介紹

4.服務熔斷

4.1 建立項目
4.2 添加hystrix座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

複製代碼
4.3 修改配置文件
spring.application.name=eureka-consumer-ribbon-breaker
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

複製代碼
4.4 修改啓動類
//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼
4.5 修改ProductService
@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:負載均衡器

    @HystrixCommand(fallbackMethod = "fallback",
            commandProperties = {
                    //默認 20 個;10s 內請求數大於 20 個時就啓動熔斷器,當請求符合熔斷條件時將觸發 getFallback()。
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,
                            value = "10"),
                    //請求錯誤率大於 50%時就熔斷,而後 for 循環發起請求,當請求符合熔斷條件時將觸發 getFallback()。
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE,
                            value = "50"),
                    //默認 5 秒;熔斷多少秒後去嘗試請求
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS,
                            value = "5000"),
            })
    public List<Product> getUsers(Integer flag) {
        System.out.println(flag);
        if (flag == 1){
            throw new RuntimeException();
        }

        //選擇調用的服務的名稱
        //ServiceInstance:封裝了服務的基本信息,如:ip、端口號
        ServiceInstance si = loadBalancerClient.choose("ego-product-provider");
        //拼接訪問服務的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9001/user/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        //ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }

    //返回託底數據的方法
    public List<Product> fallback(Integer flag) {
        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }
}

複製代碼
4.6 修改ProductController
@RestController
public class ProductController {

    @Autowired
    private ProductService userService;

    @RequestMapping("/consumer")
    public List<Product> getUsers(@RequestParam("flag") Integer flag){
        return userService.getUsers(flag);
    }
}

複製代碼
4.7 熔斷參數介紹

5.隔離(線程池隔離)

5.1 建立項目
5.2 添加座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

複製代碼
5.3 修改配置文件
spring.application.name=eureka-consumer-ribbon-threadpool
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

複製代碼
5.4 修改啓動類
//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼
5.5 修改ProductService
@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:負載均衡器

    @HystrixCommand(groupKey = "ego-product-provider",
            commandKey = "getUsers",
            threadPoolKey = "ego-product-provider", //給線程名添加前綴
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "30"),//線程池大小
                    @HystrixProperty(name = "maxQueueSize", value = "100"),//最大隊列長度
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),//線程存活時間
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15")//拒絕請求
            },
            fallbackMethod = "fallback")
    public List<Product> getUsers() {

        System.out.println(Thread.currentThread().getName());
        //選擇調用的服務的名稱
        //ServiceInstance:封裝了服務的基本信息,如:ip、端口號
        ServiceInstance si = loadBalancerClient.choose("ego-product-provider");
        //拼接訪問服務的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9001/user/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        //ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }

    //返回託底數據的方法
    public List<Product> fallback() {
        System.out.println(Thread.currentThread().getName());
        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }

    public void showThread(){
        System.out.println(Thread.currentThread().getName());
    }
}

複製代碼
5.6 修改ProductController
@RestController
public class ProductController {

    @Autowired
    private ProductService userService;

    @RequestMapping("/consumer")
    public List<Product> getUsers(){
        return userService.getUsers();
    }

    @RequestMapping("/consumer1")
    public void getUsers1(){
        userService.showThread();
    }
}

複製代碼
5.7 線程池隔離參數

6.隔離(信號量隔離)

6.1 建立項目
6.2 添加座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

複製代碼
6.3 修改配置文件
spring.application.name=eureka-consumer-ribbon-semaphore
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

複製代碼
6.4 修改啓動類
//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼
6.5 修改ProductService
@Service
public class ProductService {

    @Autowired
    private LoadBalancerClient loadBalancerClient;  //ribbon:負載均衡器

    @HystrixCommand(groupKey = "ego-product-provider",
            commandKey = "getUsers",
            threadPoolKey = "ego-product-provider", //給線程名添加前綴
            threadPoolProperties = {
                    @HystrixProperty(name = "coreSize", value = "30"),//線程池大小
                    @HystrixProperty(name = "maxQueueSize", value = "100"),//最大隊列長度
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),//線程存活時間
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15")//拒絕請求
            },
            fallbackMethod = "fallback")
    public List<Product> getUsers() {

        System.out.println(Thread.currentThread().getName());
        //選擇調用的服務的名稱
        //ServiceInstance:封裝了服務的基本信息,如:ip、端口號
        ServiceInstance si = loadBalancerClient.choose("ego-product-provider");
        //拼接訪問服務的url
        StringBuffer sb = new StringBuffer();

        //http://localhost:9001/user/product/findAll
        sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
        System.out.println(sb.toString());
        //SpringMVC RestTemplate
        RestTemplate restTemplate = new RestTemplate();
        ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
        };

        //ResponseEntity:封裝了返回值信息
        ResponseEntity<List<Product>> entity = restTemplate.exchange(sb.toString(), HttpMethod.GET, null, type);
        return entity.getBody();
    }

    //返回託底數據的方法
    public List<Product> fallback() {
        System.out.println(Thread.currentThread().getName());
        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }

    public void showThread(){
        System.out.println(Thread.currentThread().getName());
    }
}

複製代碼
6.6 信號量隔離參數

3、線程池隔離和信號量隔離的區別

4、Feign的雪崩處理

1.Feign的服務降級處理

1.1 建立項目
1.2 修改配置文件
spring.application.name=springcloud-eureka-consumer-feign-fallback
server.port=9020

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#feign默認是不開啓hystrix,默認值爲false
feign.hystrix.enabled=true

複製代碼
1.3 修改ProductConsumerService
//指定實現該接口的服務
@FeignClient(name = "ego-product-provider", fallback = ProductServiceFallback.class)
public interface ProductConsumerService {

    //查詢全部商品
    @RequestMapping(value = "/product/findAll", method = RequestMethod.GET)
    public List<Product> findAll();
}

複製代碼
1.4 添加ProductServiceFallback
@Component
public class ProductServiceFallback implements ProductConsumerService {

    /** * 可以返回託底數據的fallback方法 * @return */
    @Override
    public List<Product> findAll() {

        ArrayList<Product> list = new ArrayList<>();
        list.add(new Product(-1, "我是託底數據"));
        return list;
    }
}

複製代碼
1.5 修改ProductController
@RestController
public class ProductController {

    @Autowired
    private ProductConsumerService consumerService;
    /** * Consumer中查詢全部商品的方法 * @return */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public List<Product> list(){
        return consumerService.findAll();
    }
}

複製代碼

2.降級後的異常記錄

2.1 建立項目
2.2 添加ProductServiceFallbackFactory類
@Component
public class ProductServiceFallbackFactory implements FallbackFactory<ProductConsumerService> {

    Logger logger = LoggerFactory.getLogger(ProductServiceFallbackFactory.class);
    @Override
    public ProductConsumerService create(final Throwable throwable) {

        return new ProductConsumerService() {
            /** * 可以返回託底數據的fallback方法 * @return */
            @Override
            public List<Product> findAll() {
                logger.warn("Fallback Exception: ", throwable);
                ArrayList<Product> list = new ArrayList<>();
                list.add(new Product(-1, "我是託底數據"));
                return list;
            }
        };
    }
}

複製代碼
2.3 修改ProductConsumerService
//指定實現該接口的服務
@FeignClient(name = "ego-product-provider", fallbackFactory = ProductServiceFallbackFactory.class)
public interface ProductConsumerService {

    //查詢全部商品
    @RequestMapping(value = "/product/findAll", method = RequestMethod.GET)
    public List<Product> findAll();
}

複製代碼

5、可視化的數據監控 Hystrix-dashboard

​ Hystrix-dashboard是一款針對Hystrix進行實時監控的工具,經過Hystrix-dashboard咱們能夠直觀的看到各 Hystrix Command的請求響應時間,請求成功率等數據。

1.建立項目

2.添加座標

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-ribbon-dashboard</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-ribbon-dashboard</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

3.修改啓動類

//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼

訪問: http://localhost:9010/hystrix.stream 查看信息

4.Hystrix-dashboard監控中心

4.1 建立項目
4.2 添加座標
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-dashboard-view</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-dashboard-view</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼
4.3 修改配置文件
spring.application.name=eureka-consumer-hystrix-dashboard
server.port=1001

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

複製代碼
4.4 修改啓動類
//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼
4.5 啓動順序

​ 先啓動dashboard,再啓動dashboard-view

4.6 訪問監控中心

訪問:localhost:1001/hystrix

4.7 監控中心圖解

6、使用Turbine在多個服務與集羣狀況下收集數據監控

​ Turbine 是聚合服務器發送事件流數據的一個工具,hystrix 的 監控中,只能監控單個節點,實際生產中都爲集羣,所以能夠經過 turbine 來監控集羣服務。

1.建立Turbine項目

1.1 添加座標
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-turbine</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-turbine</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>

        <!--添加turbine座標-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-turbine</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼
1.2 修改配置文件
spring.application.name=eureka-consumer-hystrix-turbine
server.port=1002

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

#---------------------------------------turbine--------------------------
#配置 Eureka 中的 serviceId 列表,代表監控哪些服務
turbine.appConfig=eureka-consumer-ribbon-threadpool,springcloud-eureka-consumer-feign-fallback
#指定聚合哪些集羣,多個使用","分割,默認爲 default。
# 可以使用http://.../turbine.stream?cluster={clusterConfig 之一}訪問
turbine.aggregator.clusterConfig= default
# 1. clusterNameExpression 指定集羣名稱,默認表達式 appName;此時:turbine.aggregator.clusterConfig 須要配置想要監控的應用名稱;
# 2. 當 clusterNameExpression: default 時,turbine.aggregator.clusterConfig 能夠不寫,由於默認就是 default;
# 3. 當 clusterNameExpression: metadata['cluster']時,假設想要監控的應用配置了 eureka.instance.metadata-map.cluster: ABC,
# 則須要配置,同時 turbine.aggregator.clusterConfig:ABC
turbine.clusterNameExpression="default"

複製代碼
1.3 修改啓動類
@SpringBootApplication
@EnableTurbine
public class HystrixTurbineApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixTurbineApplication.class, args);
    }
}

複製代碼

2.使用Turbine聚合多個服務

2.1 修改被聚合的項目的pom文件,添加dashboard的座標
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>

複製代碼
2.2 修改被監控的服務的啓動類
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
//必須添加以下兩個註解
@EnableCircuitBreaker
@EnableHystrixDashboard
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

}

複製代碼
2.3 查看turbine整合成功後的監控地址

查看:http://localhost:1002/turbine.stream

7、使用RabbitMQ收集、監控數據

使用RabbitMQ能夠解決服務與turbine緊耦合問題,另外使用tuebine須要在配置文件中指定須要收集的服務名,若是服務不少的話,配置起來也比較麻煩。

1.建立Consumer服務

2.添加座標

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-ribbon-dashboard-mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-ribbon-dashboard-mq</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

3.修改consumer的配置文件

spring.application.name=eureka-consumer-ribbon-dashboard
server.port=9010

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
spring.rabbitmq.virtual-host=/

複製代碼

4.修改啓動類

//開啓熔斷器
@EnableCircuitBreaker
//表示Eureka的客戶端
@EnableEurekaClient
@SpringBootApplication
@EnableHystrix
@EnableHystrixDashboard
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

複製代碼

5.建立Turbine項目

6.爲Turbine項目添加依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.13.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luyi</groupId>
    <artifactId>springcloud-eureka-consumer-turbine-mq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud-eureka-consumer-turbine-mq</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

複製代碼

7.修改Turbine的配置文件

spring.application.name=eureka-consumer-hystrix-turbine
server.port=1002

#設置服務註冊中心地址,向全部註冊中心作註冊
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/

#rabbitmq與turbine相鏈接
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
spring.rabbitmq.virtual-host=/

複製代碼

8.修改Turbine啓動類

@SpringBootApplication
@EnableTurbineStream
public class HystrixTurbineApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixTurbineApplication.class, args);
    }
}

複製代碼
相關文章
相關標籤/搜索