一、熔断器简介
1、简介
在微服务系统中是一款提供保护机制的组件 。参考网址:https://github.com/Netflix/Hystrix
是Netflix公司的开源一个延迟和容错库,用户隔离访问远程服务,第三方库,防止出现级联失败
2、雪崩问题
微服务中调用关系错综复杂一个需求可能需要多个接口才能实现,会形成复杂的调用链路,如下图:
其中某一个线路出现发生异常,请求堵塞,用户得不到响应,tomcat不释放当前线程,造成线程阻塞。导致服务资源被耗尽。从而大面积宕机。
解决手段:服务降级,包括线程隔离、服务降级。
二、线程隔离&服务降级(解决雪崩效应)
- 线程隔离 -- 用户请求不是直接访问服务,使用线程池中的空闲线程访问服务,加速失败判断时间。
- 服务降级 -- 及时返回服务调用失败的结果,让线程不因等待而阻塞。
解读:
1、Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池满了调用被拒绝默认默认采用不排队,加速失败判断时间
2、用户请求不直接访问服务,通过线程池的空闲线程访问,线程池已满或请求超时,则自动降级。
三、项目引用
1、pom.xml
1 <dependency> 2 <groupId>org.springframework.cloud</groupId> 3 <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> 4 </dependency>
2、启动类添加注解 @EnableCircuitBreaker
3、降级逻辑 调用方法添加注解 @HystrixCommand(fallbackMethod = "降级方法") 降级方法和本方法保持一致返回类型,一般String
1 package com.liuxn.cloud.controller; 2 3 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 4 import org.slf4j.Logger; 5 import org.slf4j.LoggerFactory; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.web.bind.annotation.GetMapping; 8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.RequestMapping; 10 import org.springframework.web.bind.annotation.RestController; 11 import org.springframework.web.client.RestTemplate; 12 13 /** 14 * Ribbon 应用 15 * 16 * @author liuxn 17 * @date 2020/12/7 18 */ 19 @RestController 20 @RequestMapping("/consumer/v2") 21 public class ConsumerControllerV2 { 22 private static Logger logger = LoggerFactory.getLogger(ConsumerControllerV2.class); 23 24 25 /** 26 * Ribbon :在执行restTemplate发送服务地址请求时,使用负载均衡拦截器,根据服务名获取服务地址列表。使用Ribbon负载均衡算法 选择已和服务地址。并访问改地址。 步骤: 1、启动多个生产者实例 27 * 2、修改RestTemplate 添加负载均衡注解 @LoadBalanced 启动是spring_cloud-commons.jar 中的 META-INF/spring.factories中LoadBalancerAutoConfiguration 28 * LoadBalancerInterceptorConfig负载均衡拦截器 默认是轮询算法 配置成随机在消费者配置文件中 源码跟踪 显然是有组件根据service名称,获取到了服务实例的ip和端口。因为consumer-demo使用的是RestTemplate,spring的负载均衡自动配置类LoadBalancerAutoConfiguration.LoadBalancerInterceptorconfig会自动配置负载均衡拦截器(在spring-cloud-commons-*.jar包中的spring.factories中定义的自动配置类),它就是 29 * LoadBalancerInterceptor,这个类会在对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,随后利用负载均衡算法得到真实的服务地址信息,替换服务id。 30 */ 31 32 @Autowired 33 private RestTemplate restTemplate; 34 35 @GetMapping("/{id}") 36 @HystrixCommand(fallbackMethod = "fallBackGetDemo") 37 public String getDemo(@PathVariable int id) { 38 String url = "http://springcloud-eureka-provider/provider/" + id; 39 return restTemplate.getForObject(url, String.class); 40 } 41 42 public String fallBackGetDemo(int id) { 43 logger.info("查询demo对象,Id:[{}]网络失败", id); 44 return "error ,网络拥挤!"; 45 } 46 47 }
消费者无法调用服务,或者调用异常时,接口会返回 error ,网络拥挤!
使用全局降级:类名添加注解@DefaultProperties(defaultFallback = "defaultFallback") 方法上添加注解 @HystrixCommand 使用全局降级减少代码维护工作量
1 package com.liuxn.cloud.controller; 2 3 import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties; 4 import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.web.bind.annotation.GetMapping; 9 import org.springframework.web.bind.annotation.PathVariable; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.RestController; 12 import org.springframework.web.client.RestTemplate; 13 14 /** 15 * Ribbon 应用 16 * 17 * @author liuxn 18 * @date 2020/12/7 19 */ 20 @RestController 21 @RequestMapping("/consumer/v2") 22 @DefaultProperties(defaultFallback = "defaultFallback") 23 public class ConsumerControllerV2 { 24 private static Logger logger = LoggerFactory.getLogger(ConsumerControllerV2.class); 25 26 27 /** 28 * Ribbon :在执行restTemplate发送服务地址请求时,使用负载均衡拦截器,根据服务名获取服务地址列表。使用Ribbon负载均衡算法 选择已和服务地址。 29 * 并访问改地址。 步骤: 30 * 1、启动多个生产者实例 31 * 2、修改RestTemplate 添加负载均衡注解 @LoadBalanced 启动是spring_cloud-commons.jar 中的 32 * META-INF/spring.factories中LoadBalancerAutoConfiguration 33 * LoadBalancerInterceptorConfig负载均衡拦截器 默认是轮询算法 配置成随机在消费者配置文件中 源码跟踪 显然是有组件根据service名称, 34 * 获取到了服务实例的ip和端口。因为consumer-demo使用的是RestTemplate,spring的负载均衡自动配置类LoadBalancerAutoConfiguration. 35 * LoadBalancerInterceptorconfig会自动配置负载均衡拦截器(在spring-cloud-commons-*.jar包中的spring.factories中定义的自动配置类),它就是 36 * LoadBalancerInterceptor,这个类会在对RestTemplate的请求进行拦截,然后从Eureka根据服务id获取服务列表,随后利用负载均衡算法得到真实的服务地址信息,替换服务id。 37 */ 38 39 @Autowired 40 private RestTemplate restTemplate; 41 42 @GetMapping("/{id}") 43 //@HystrixCommand(fallbackMethod = "fallBackGetDemo") 44 @HystrixCommand //配合DefaultProperties 统一管理降级方法 45 public String getDemo(@PathVariable int id) { 46 String url = "http://springcloud-eureka-provider/provider/" + id; 47 return restTemplate.getForObject(url, String.class); 48 } 49 50 public String fallBackGetDemo(int id) { 51 logger.info("查询demo对象,Id:[{}]网络失败", id); 52 return "error ,网络拥挤!"; 53 } 54 55 56 public String defaultFallback() { 57 logger.info("默认提示,,error ,网络拥挤!"); 58 return "默认提示:error ,网络拥挤!"; 59 } 60 61 }
网络超时默认时间为1s,可以通过以下超时配置。 单位:ms
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2000
faultProperties(defaultFallback = "defaultFallback")