Изучение SpringCloud Hystrix проведет вас от 0 до 1

Java

Во-первых, что такое катастрофический лавинный эффект

1. Процесс лавинного явления

В нормальных условиях запрос передается службе T через несколько служб, а служба T обрабатывает и возвращает шаг за шагом.

Когда служба B получает большое количество запросов, служба T, которая в конечном итоге обрабатывает службу, будет испытывать давление, что приведет к сбою службы.

Поскольку служба T парализована первой, запросы будут задерживаться в службе U. Когда нагрузка станет слишком высокой, системы на всех уровнях рухнут, что сделает все службы на этой линии недоступными.

Выход из строя одной линии повлияет и на другие линии, поэтому вся система рухнет.

2. Причины схода лавин

  • Поставщик услуг недоступен (аппаратный сбой, программная ошибка, сбой кэша, большой объем пользовательских запросов)
  • Повторите попытку для увеличения трафика (повторная попытка пользователя, повторная попытка логики кода)
  • Вызывающая служба недоступна (исчерпание ресурсов из-за синхронных ожиданий)

Конечным результатом является то, что одна служба недоступна, и даже несколько служб недоступны, что в конечном итоге приводит к полному параличу системы.

2. Как решить катастрофический лавинный эффект

  • понизить рейтинг

    Тайм-аут для понижения, когда ресурсов (потока или семафора) недостаточно для понижения, после понижения вы можете сотрудничать с интерфейсом понижения, чтобы вернутьсяБазовые данные.

    Реализуйте резервный метод. Когда в серверной службе запросов возникает исключение, для возврата значения можно использовать резервный метод.

  • Изоляция (изоляция пула потоков и изоляция семафоров)

    Ограничьте использование ресурсов для вызова распределенных служб. Проблема с одной вызываемой службой не повлияет на вызовы других служб.

  • предохранитель

    Когда частота отказов (отказ сети, частота отказов, вызванная тайм-аутом) достигает порогового значения, автоматически запускается переход на более раннюю версию, а быстрый отказ, вызванный предохранителем, выполняет быстрое восстановление.

  • тайник

    кэширование запросов

  • запрос на вытягивание

    Обеспечьте слияние запросов на вытягивание

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 Изменить ПродуктСервис
@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

Решение: вы можете использовать кеш весны

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 Изменить ПродуктСервис
@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 Недостатки запросов на слияние

После настройки слияния запросов для выполнения запроса требуется всего 5 мс, но после использования слияния запросов вам может потребоваться подождать еще 10 мс, чтобы увидеть, есть ли другие запросы вместе, чтобы один запрос увеличился с 5 мс до 15 мс. Однако, если команда, которую мы инициируем, изначально является командой с высокой задержкой, то в это время можно использовать слияние запросов, поскольку потребление времени временного окна в это время незначительно.Высокое совпадение также является важным сценарием для слияния запроса.

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 Изменить ПродуктСервис
@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 модифицируют контроллер
@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 Добавление координат гистрикса
<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 Изменить ПродуктСервис
@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. Лавинное обращение Фейна

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.

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 Последовательность запуска

Сначала запустите приборную панель, затем запустите панель мониторинга.

4.6 Центр контроля доступа

Доступ: локальный: 1001/hystrix

4.7 Схема центра мониторинга

6. Используйте Turbine для сбора данных мониторинга в нескольких сервисах и кластерах.

Turbine — это инструмент для сервера агрегации для отправки данных потока событий.При мониторинге hystrix можно отслеживать только один узел, а фактическое производство представляет собой кластер, поэтому службу кластера можно отслеживать через турбину.

1. Создайте проект турбины

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 агрегированного проекта и добавьте координаты приборной панели
<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 Просмотр адреса мониторинга после успешной интеграции турбины

Проверить:http://localhost:1002/turbine.stream

7. Используйте RabbitMQ для сбора и мониторинга данных

Использование RabbitMQ может решить проблему тесной связи между сервисами и турбиной.Кроме того, при использовании tuebine нужно указывать имя сервиса, который нужно собрать в конфигурационном файле.Если сервисов много, то и настраивать сложнее.

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-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. Измените файл конфигурации потребителя

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. Создайте проект турбины

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. Измените класс запуска турбины.

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