美文网首页
Spring Cloud学习day101:Hystrix(二)

Spring Cloud学习day101:Hystrix(二)

作者: 开源oo柒 | 来源:发表于2019-12-09 22:11 被阅读0次

    一、信号隔离机制

    解决灾难性雪崩效应使用隔离机制中的信号量隔离处理。

    1.什么是信号量隔离:

    hystrix里面,核心的一项功能,其实就是所谓的资源隔离,要解决的最最核心的问题,就是将多个依赖服务的调用分别隔离到各自自己的资源池内。避免对某一个依赖服务的调用,因为依赖服务的接口调用的延迟或者失败,导致服务所有的线程资源全部耗费在这个服务的接口调用上。

    示例

    2.测试信号量隔离

    • 信号隔离注解中的参数:
    参数 作用 默认值
    EXECUTION_ISOLATION_STRATEGY 隔离策略的配置项 THREAD
    EXECUTION_ISOLATION_THREAD_TIMEOUTINMILLISECONDS 超时时间 1000ms
    EXECUTION_ISOLATION_THREAD_INTERRUPTONTIMEOUT 是否打开超时线程中断 TRUE
    EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS 信号量最大并发度 10
    FALLBACK_ISOLATION_SEMAPHORE_MAX_CONCURRENTREQUESTS fallback最大并发度 10
    • 创建Provider:

    下面测试中会多次使用该服务和Service。

    Provider
    • 修改POM文件:
        <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>
            <!-- 添加product-service坐标 -->
            <dependency>
                <groupId>com.zlw</groupId>
                <artifactId>springcloud-eureka-ribbon-hystrix-service</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=product-provider-hystix
    server.port=9011
    
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    • 创建启动类:
    @EnableEurekaClient
    @SpringBootApplication
    public class ProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ProviderApplication.class, args);
        }
    }
    
    • 编写Controller提供服务:
    @RestController
    public class ProductController implements  ProductService{
    
        @Override
        public List<Product> findAll() {
            List<Product> list = new ArrayList<Product>();
            list.add(new Product(1,"手机"));
            list.add(new Product(2,"电脑"));
            list.add(new Product(3,"电视"));
            return list;
        }
    }
    
    • 创建项目Service:


      示例
    • 修改POM文件,添加坐标:
        <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>
        </dependencies>
    
    • 创建实体类:
    public class Product {
        private int id;
        private String name;
    
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Product(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public Product() {
            super();
        }
    }
    
    • 编写Service接口:
    @RequestMapping("/product")
    public interface ProductService {
        // 查询所有
        @RequestMapping(value = "/findAll", method = RequestMethod.GET)
        public List<Product> findAll();
    }
    
    • 创建consumer-semaphore:


      Consumer
    • 修改POM文件:
        <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.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>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-semaphore
    server.port=9007
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    • 创建实体类:
        private int id;
        private String name;
    
    • 创建Service:
    @Service
    public class ProductService {
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        @HystrixCommand(fallbackMethod = "fallback", commandProperties = {
                @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),
                // 信号量 隔离
                @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "100")
                // 信号量最大并度
        })
        public List<Product> getProduct() {
            // 选择调用的服务的名称
            // ServiceInstance 封装了服务的基本信息,如 IP,端口
            ServiceInstance si = this.loadBalancerClient.choose("product-provider-hystix");
            // 拼接访问服务的URL
            StringBuffer sb = new StringBuffer();
            // http://localhost:9001/product/findAll
            sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
            System.out.println(sb.toString());
            // springMVC RestTemplate
            RestTemplate rt = new RestTemplate();
    
            ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
            };
    
            // ResponseEntity:封装了返回值信息
            ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
            List<Product> list = response.getBody();
            return list;
        }
    
        // 托底数据
        public List<Product> fallback() {
            System.out.println(Thread.currentThread().getName());
            List<Product> list = new ArrayList<Product>();
            list.add(new Product(-1, "托底数据"));
            return list;
        }
    
        public void showThread() {
        System.out.println(Thread.currentThread().getName());
        }
    }
    
    • 创建Controller:
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @RequestMapping("/list")
        public List<Product> list() {
            return this.productService.getProduct();
        }
    }
    
    • 创建启动类:
    @EnableCircuitBreaker
    @EnableEurekaClient
    @SpringBootApplication
    public class SemaphoreApplication {
        public static void main(String[] args) {
            SpringApplication.run(SemaphoreApplication.class, args);
        }
    }
    
    • 测试:


      示例
      控制台输出

    3.线程池和信号隔离的区别:

    -- 线程池隔离 信号量隔离
    线程 请求线程和调用provider线程不是同一条线程 请求线程和调用provider线程是同一条线程
    开销 排队、调度、上下文开销等 无线程切换,开销低
    异步 支持 不支持
    并发支持 支持(最大线程池大小) 支持(最大信号量上限)
    传递Header 不可以 可以
    是否支持超时 支持 不支持
    • 什么情况下使用线程池隔离:

    请求并发量大,并且耗时长(请求耗时长一般是计算量大,或读数据库);采用线程隔离策略,这样可以保证大量的容器线程可用,不会由于服务原因,一直处于阻塞状态,快速失败返回。

    • 什么情况下使用信号隔离:

    请求并发量大,并且耗时短(请求耗时短可能是计算量小,或读缓存);采用信号量隔离策略,因为这类服务的返回通常会非常的块,不会占用容器线程太长时间,而且也会减少了线程切换的一些开销,提高了缓存服务的效率。


    二、Feign的服务降级

    1.服务降级测试:

    • 创建Consumer-fallback


      使用Feign
    • 修改POM文件:
        <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>
            <!-- 添加 Feign 坐标 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            </dependency>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-feign-fallback
    server.port=9020
     
    #设置服务注册中心地址,指向另一个注册中心 
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/ 
     
    #Feign 默认是不开启 Hystrix 的。默认为:false 
    feign.hystrix.enabled=true
    
    • 创建实体类:
        private int id;
        private String name;
    
    • 创建Service接口:
    @FeignClient(name = "product-provider",fallback = ProductConsumerFallback.class)
    public interface ConsumerService {
        
        @RequestMapping(value = "/product/findAll",method = RequestMethod.GET)
        public List<Product>findAll();
    }
    
    • 创建托底数据:
    @Component
    public class ProductConsumerFallback implements ConsumerService {
    
        // 返回托底数据的方法
        @Override
        public List<Product> findAll() {
            ArrayList<Product> list = new ArrayList<>();
            list.add(new Product(-1, "托底数据"));
            return list;
        }
    }
    
    • 创建Controller:
    @RestController
    public class ProductController {
    
        @Autowired
        ConsumerService consumerService;
    
        // 查询所有
        @RequestMapping(value = "list", method = RequestMethod.GET)
        public List<Product> list() {
            List<Product> list = consumerService.findAll();
            return list;
        }
    }
    
    • 修改启动类:
    @EnableCircuitBreaker
    @EnableHystrixDashboard
    @EnableFeignClients
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    
    • 测试:


      正常数据
      示例

    2.服务降级后的异常记录:

    • 为什么记录降级后的异常信息?

    我们调用provider服务的时候出现了故障从而返回了托底数据,我们怎么查看故障的日志信息呢?前面的处理我们是无法获取到consumer调用provider的错误信息的。此时就需要记录异常信息,方便查看异常。

    • 创建测试项目:


      示例
    • 修改POM文件:
        <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>
            <!-- 添加 Feign 坐标 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-feign</artifactId>
            </dependency>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-feign-factory
    server.port=9021
     
    #设置服务注册中心地址,指向另一个注册中心 
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/ 
     
    #Feign 默认是不开启 Hystrix 的。默认为:false 
    feign.hystrix.enabled=true
    
    • 修改Service:
    @FeignClient(name = "product-provider",fallbackFactory = ProductConsumerFactory.class)
    public interface ConsumerService {
        
        @RequestMapping(value = "/product/findAll",method = RequestMethod.GET)
        public List<Product>findAll();
        
    }
    
    • 修改Hystrix:
    @Component
    public class ProductConsumerFactory implements FallbackFactory<ConsumerService> {
        Logger logger = LoggerFactory.getLogger(ProductConsumerFactory.class);
    
        @Override
        public ConsumerService create(Throwable cause) {
    
            return new ConsumerService() {
                // 返回托底数据的方法
                @Override
                public List<Product> findAll() {
                    logger.warn("FallBack Exception:",cause);
                    ArrayList<Product> list = new ArrayList<>();
                    list.add(new Product(-1, "托底数据"));
                    return list;
                }
            };
        }
    }
    
    • 修改启动类:
    @EnableFeignClients
    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConsumerApplication.class, args);
        }
    }
    
    • 测试:


      正常数据
      错误数据
      控制台信息

    三、可视化数据监控dashboard

    1.什么是Hystrix-dashboard?

    Hystrix-dashboard 是一款针对 Hystrix 进行实时监控的工具,通过 Hystrix Dashboard 我们可以在直观地看到各 Hystrix Command 的请求响应时间, 请求成功率等数据。

    • @EnableHystrix注解的作用:

    启动熔断降级服务。

    • @EnableHystrixDashboard注解的作用:

    开启HystrixDashboard。

    2.创建项目测试数据监控:

    • 创建数据监控中心服务:


      示例
    • 修改POM文件:
        <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.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-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            </dependency>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-ribbon-dashboard
    server.port=9009
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    • 创建实体类:
        private int id;
        private String name;
    
    • 创建Service:
    @Service
    public class ProductService {
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        @HystrixCommand(groupKey = "product-provider", commandKey = "getProduct", threadPoolKey = "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> getProduct() {
            // 选择调用的服务的名称
            // ServiceInstance 封装了服务的基本信息,如 IP,端口
            ServiceInstance si = this.loadBalancerClient.choose("product-provider-hystix");
            // 拼接访问服务的URL
            StringBuffer sb = new StringBuffer();
            // http://localhost:9001/product/findAll
            sb.append("http://").append(si.getHost()).append(":").append(si.getPort()).append("/product/findAll");
            System.out.println(sb.toString());
            // springMVC RestTemplate
            RestTemplate rt = new RestTemplate();
    
            ParameterizedTypeReference<List<Product>> type = new ParameterizedTypeReference<List<Product>>() {
            };
    
            // ResponseEntity:封装了返回值信息
            ResponseEntity<List<Product>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type);
            List<Product> list = response.getBody();
            return list;
        }
    
        // 托底数据
        public List<Product> fallback() {
            System.out.println(Thread.currentThread().getName());
            List<Product> list = new ArrayList<Product>();
            list.add(new Product(-1, "托底数据"));
            return list;
        }
    
        public void showThread() {
            System.out.println(Thread.currentThread().getName());
        }
    }
    
    • 创建Controller:
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @RequestMapping("/list")
        public List<Product> list() {
            return this.productService.getProduct();
        }
    
    • 修改启动类:
    @EnableHystrix
    @EnableHystrixDashboard
    @EnableCircuitBreaker
    @EnableEurekaClient
    @SpringBootApplication
    public class DashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(DashboardApplication.class, args);
        }
    }
    
    • 测试:


      示例
      关闭Provider
      示例
    • 创建Hystrix-dashboard监控中心:


      示例
    • 修改POM文件:
        <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.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-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            </dependency>
        </dependencies>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-dashboard-view
    server.port=1001
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    
    • 修改启动类:
    @EnableHystrix
    @EnableHystrixDashboard
    @EnableCircuitBreaker//开启熔断器
    @EnableEurekaClient
    @SpringBootApplication
    public class DashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(DashboardApplication.class, args);
        }
    }
    
    • 测试:

    启动顺序,先启动服务再启动监控中心。

    示例
    首页介绍
    监控中心图解

    四、使用Turbine集合集群

    1.什么是Turbine?

    Turbine 是聚合服务器发送事件流数据的一个工具,hystrix 的
    监控中,只能监控单个节点,实际生产中都为集群,因此可以通过 turbine 来监控集群服务。

    示例

    2.创建项目测试:

    使用Turbine聚合Consumer-fallback和Consumer-dashboard项目。

    Turbine-view
    • 修改POM文件:
        <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.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-starter-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>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-turbine-view
    server.port=1002
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    #----------------------turbine---------------
    #配置 Eureka 中的 serviceId 列表,表明监控哪些服务 
    turbine.appConfig=eureka-consumer-feign-fallback,eureka-consumer-ribbon-dashboard
    #指定聚合哪些集群,多个使用","分割,默认为 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"
    
    • 修改启动类:
    @EnableTurbine
    @SpringBootApplication
    public class TurbineApplication {
        public static void main(String[] args) {
            SpringApplication.run(TurbineApplication.class, args);
        }
    }
    
    • 修改聚合多个服务的POM文件,添加坐标:
    <dependency>    
    <groupId>org.springframework.cloud</groupId>    
    <artifactId>spring-cloud-starter-hystrix</artifactId>   
    </dependency>                  
    <dependency>             
    <groupId>org.springframework.boot</groupId>             
    <artifactId>spring-boot-starter-actuator</artifactId>         
    </dependency> 
     <dependency>             
    <groupId>org.springframework.cloud</groupId>             
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId >         
    </dependency>  
    
    • 修改被监控服务的启动类,添加注解:
    @EnableHystrixDashboard 
    @EnableCircuitBreaker //开启熔断器 断路器
    
    • 测试:

    依次启动服务和监控中心。

    示例

    3.监控集群:

    将任意服务打包后,上传到Linux服务器,在/usr/local/目录下创建目录,“mkdir 目录名”,添加启动脚本。

    示例
    • 测试:

    依次启动服务和监控中心。

    示例.png

    五、使用RabbitMQ收集监控数据(RabbitMQ+Turbine+dashboard)

    1.为什么使用RabbitMQ?

    使用的Turbine进行数据监控的虽然能够解决的集群服务的监控的问题,但是的也存在问题,比如频繁的配置,我们需要在Turbine内配置需要监控的服务,这是非常不好的,假如有1000个服务?那配置起来就很繁琐了,而且配置的服务不易管理,增加了管理的难度。
    在实际的应用中我们并不采用turbine进行集群服务的监控,而是采用在服务和Turbine之间添加一个的TabbitMQ进行数据的收集,然后将Trubine从RabbitMQ中获取数据,在交给Dashboard进行显示。

    未使用RabbitMQ 使用RabbitMQ

    2.RabbitMQ收集监控数据的步骤:

    • 修改Consumer的配置信息:
      (1)在POM文件中添加坐标:dashboard、actuator、hystrix-stream、stream-rabbit。
      (2)修改配置文件:添加RabbitMQ的连接信息。
    spring.rabbitmq.host=192.168.226.129
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=admin
    spring.rabbitmq.virtualHost=/ 
    

    (3)修改启动类:添加@EnableHystrixDashboard注解。

    • 修改Turbine的配置信息:
      (1)修改POM文件,添加Turbine-stream和stream-Rabbit的坐标。
      (2)修改配置文件:
    spring.rabbitmq.host=192.168.226.129
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=admin
    spring.rabbitmq.virtualHost=/ 
    

    (3)修改启动类,添加@EnableTurbineStream注解,开启Turbine-Stream的监控。

    3.创建测试项目:

    需要在Linux服务器中安装RabbitMQ。RabbitMQ安装和使用

    • 创建Consumer服务:


      示例
    • 修改POM文件:
        <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.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-starter-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>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-ribbon-dashboard-mq
    server.port=9021
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    
    spring.rabbitmq.host=192.168.226.129
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=admin
    spring.rabbitmq.virtualHost=/
    
    
    • 创建实体类:
        private int id;
        private String name;
    
    • 创建Service:
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @RequestMapping("/list")
        public List<Product> list() {
            return this.productService.getProduct();
        }
    }
    
    • 创建Controller:
    @RestController
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @RequestMapping("/list")
        public List<Product> list() {
            return this.productService.getProduct();
        }
    }
    
    • 修改启动类:
    @EnableHystrix
    @EnableHystrixDashboard
    @EnableCircuitBreaker
    @EnableEurekaClient
    @SpringBootApplication
    public class DashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(DashboardApplication.class, args);
        }
    }
    
    • 创建Turbine-mq:


      示例
    • 修改POM文件:
        <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.cloud</groupId>
                <artifactId>spring-cloud-starter-config</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>
    
    • 修改配置文件:
    spring.application.name=eureka-consumer-turbine-mq
    server.port=1002
    
    #设置服务注册中心
    eureka.client.serviceUrl.defaultZone=http://admin:123456@eureka1:8761/eureka/,http://admin:123456@eureka2:8761/eureka/
    spring.rabbitmq.host=192.168.226.129
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=admin
    spring.rabbitmq.password=admin
    spring.rabbitmq.virtualHost=/
    
    • 修改启动类:
    @EnableTurbineStream
    @SpringBootApplication
    public class TurbineApplication {
        public static void main(String[] args) {
            SpringApplication.run(TurbineApplication.class, args);
        }
    }
    
    • 测试:


      示例
    示例

    相关文章

      网友评论

          本文标题:Spring Cloud学习day101:Hystrix(二)

          本文链接:https://www.haomeiwen.com/subject/zlyigctx.html