spring_cloud之熔断器(Hystrix)

一、熔断器简介

  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")
posted @ 2020-12-22 17:32  爱,诗意永存  阅读(748)  评论(0编辑  收藏  举报