正常情况下请求经过多个服务传到服务T,服务T进行处理并逐级返回。
当服务B接收到了大量的请求时,最终处理服务的服务T会受到压力,导致服务崩掉。
因为服务T最先瘫痪,请求就会积压在服务U,当压力过大时各级系统都会崩掉,这样就令这条线路的服务全部不可用了。
一个线路的瘫痪也会影响到其他线路,这样整个系统就会崩掉了
最终的结果就是一个服务不可用,连带着多个服务都不可用,最终导致系统全面瘫痪。
降级
超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回 托底数据 。
实现一个fallback方法,当请求后端服务出现异常的时候,可以使用fallback方法返回值。
隔离(线程池隔离和信号量隔离)
限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
熔断
当失败率(网络故障、超时造成的失败率)达到阈值自动触发降级,熔断器触发的快速失败会进行快速恢复
缓存
提供了请求缓存
请求合并
提供请求合并
对服务做降级处理
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 复制代码
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/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
@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; } } 复制代码
Hystrix为了降低访问服务的频率,支持将一个请求与返回结果做缓存处理,如果再次请求的url没有变化,那么hystrix不会请求服务,而是直接从缓存中将结果返回,这样可以大大降低访问服务的压力。
Hystrix自带缓存,有以下两个缺点
1.是一个本地缓存,在集群情况下缓存是同步的。
2.不支持第三方缓存容器。如:Redis、Memcache
解决:可以使用spring的缓存
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 复制代码
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 复制代码
@EnableCaching //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
@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); } } 复制代码
@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); } } 复制代码
在微服务架构中会拆分成多个小的模块,各个模块之间进行调用是需要通信的,但是在并发量大的情况下会令大量线程处于等待状态,这就会增加响应时间,所以可以使用请求合并将多次请求合并为一次请求。
在设置了请求合并以后,本来一次请求只需要5ms就搞定了,但是使用了请求合并后可能还需要再等待10ms,看看还有没有其他请求一起,这样一次请求就从5ms增加到了15ms。不过如果我们发起的命令本来就是一个高延迟的命令,那么这个时候就可以使用请求合并了,因为这个时候时间窗的时间消耗就显得微不足道了。 高并发也是请求合并的重要场景 。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 复制代码
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/ 复制代码
@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; } } 复制代码
@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()); } } 复制代码
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 复制代码
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/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
@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; } } 复制代码
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer") public List<Product> getUsers(@RequestParam("flag") Integer flag){ return userService.getUsers(flag); } } 复制代码
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 复制代码
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/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
@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()); } } 复制代码
@RestController public class ProductController { @Autowired private ProductService userService; @RequestMapping("/consumer") public List<Product> getUsers(){ return userService.getUsers(); } @RequestMapping("/consumer1") public void getUsers1(){ userService.showThread(); } } 复制代码
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 复制代码
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/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
@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()); } } 复制代码
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 复制代码
//指定实现该接口的服务 @FeignClient(name = "ego-product-provider", fallback = ProductServiceFallback.class) public interface ProductConsumerService { //查询所有商品 @RequestMapping(value = "/product/findAll", method = RequestMethod.GET) public List<Product> findAll(); } 复制代码
@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; } } 复制代码
@RestController public class ProductController { @Autowired private ProductConsumerService consumerService; /** * Consumer中查询所有商品的方法 * @return */ @RequestMapping(value = "/list", method = RequestMethod.GET) public List<Product> list(){ return consumerService.findAll(); } } 复制代码
@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; } }; } } 复制代码
//指定实现该接口的服务 @FeignClient(name = "ego-product-provider", fallbackFactory = ProductServiceFallbackFactory.class) public interface ProductConsumerService { //查询所有商品 @RequestMapping(value = "/product/findAll", method = RequestMethod.GET) public List<Product> findAll(); } 复制代码
Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix-dashboard我们可以直观的看到各 Hystrix Command的请求响应时间,请求成功率等数据。
<?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> 复制代码
//开启熔断器 @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 查看信息
<?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> 复制代码
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/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication @EnableHystrix @EnableHystrixDashboard public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
先启动dashboard,再启动dashboard-view
访问:localhost:1001/hystrix
Turbine 是聚合服务器发送事件流数据的一个工具,hystrix 的 监控中,只能监控单个节点,实际生产中都为集群,因此可以通过 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</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> 复制代码
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" 复制代码
@SpringBootApplication @EnableTurbine public class HystrixTurbineApplication { public static void main(String[] args) { SpringApplication.run(HystrixTurbineApplication.class, args); } } 复制代码
<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> 复制代码
@EnableDiscoveryClient @EnableFeignClients @SpringBootApplication //必须添加如下两个注解 @EnableCircuitBreaker @EnableHystrixDashboard public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
查看: http://localhost:1002/turbine.stream
使用RabbitMQ可以解决服务与turbine紧耦合问题,另外使用tuebine需要在配置文件中指定需要收集的服务名,如果服务很多的话,配置起来也比较麻烦。
<?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> 复制代码
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=/ 复制代码
//开启熔断器 @EnableCircuitBreaker //表示Eureka的客户端 @EnableEurekaClient @SpringBootApplication @EnableHystrix @EnableHystrixDashboard public class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); } } 复制代码
<?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> 复制代码
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=/ 复制代码
@SpringBootApplication @EnableTurbineStream public class HystrixTurbineApplication { public static void main(String[] args) { SpringApplication.run(HystrixTurbineApplication.class, args); } } 复制代码