Spring Cloud学习day101:Hystrix(二)

一、信号隔离机制

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

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);
    }
}
  • 测试:


    示例
示例
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容