十一、一文搞定spring cloud重要成员--Hystrix(断路器)

由来

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。 为了解决这个问题,业界提出了断路器模型。

是什么

Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的,较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

具体使用

依赖

<!--断路器依赖-->
 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-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-netflix-hystrix-dashboard</artifactId>
 </dependency>

在restTemplate+ribbon方式下

  1. 改造service

    在方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法

    @Service
     public class HelloService {
     ​
         @Resource
         RestTemplate restTemplate;
     ​
         @HystrixCommand(fallbackMethod = "error")
         public String helloService(){
             return restTemplate.getForObject("http://user-service/hello",String.class);
         }
     ​
         public String error(){
             return "error";
         }
     ​
     }
  2. 开启熔断:启动类

    @SpringBootApplication
     @EnableEurekaClient //标识Eureka客户端
     @EnableHystrix  //开启断路器
     @EnableHystrixDashboard //开启断路器仪表盘
     public class ConsumerRibboApplication {
     ​
        public static void main(String[] args) {
           SpringApplication.run(ConsumerRibboApplication.class, args);
        }
     ​
        //向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
           return new RestTemplate();
        }
     ​
        //加入断路器仪表盘,注入bean
        @Bean
        public ServletRegistrationBean getServlet(){
           HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
           ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
           registrationBean.setLoadOnStartup(1);
           registrationBean.addUrlMappings("/actuator/hystrix.stream");
           registrationBean.setName("HystrixMetricsStreamServlet");
           return registrationBean;
        }
     }
  3. 查看仪表盘

    http://localhost:8002/hystrix

     

    输入URL:http://localhost:8002/actuator/hystrix.stream

     

  4. 设置超时时间(默认1s)

    可以使用设置commandProperties属性来设置:execution.isolation.thread.timeoutInMilliseconds

    @HystrixCommand(fallbackMethod = "error",
             commandProperties = {
                 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500")
             })
     public String helloService(){
         return restTemplate.getForObject("http://user-service/hello",String.class);
     }

    关闭超时设置:execution.timeout.enabled设为false

     @HystrixCommand(fallbackMethod = "error",
             commandProperties = {
                 @HystrixProperty(name = "execution.timeout.enabled", value = "false")
             })
     public String helloService(){
         return restTemplate.getForObject("http://user-service/hello",String.class);
     }

    其它值得关注的属性

    circuitBreaker.requestVolumeThreshold:在给定的时间范围内,方法应该被调用的次数

    circuitBreaker.errorThresholdPercentage:在给定的时间范围内,方法调用产生失败的百分比

    metrics.rollingStats.timeInMilliseconds:控制请求量和错误百分比的滚动时间周期

    circuitBreaker.sleepWindowInMilliseconds:处于打开状态的断路器要经过多长时间才会进入到半开状态,进入半开状态之后,将会再次尝试失败的原始方法。

在feign方式下

  1. 添加配置开启断路器

     feign:
       hystrix:
         enabled: true #开启断路器
  2. 创建熔断处理类,实现对应接口

     @Component
     public class ErrorHander implements HelloAction {
         @Override
         public String hello() {
             return "feign error";
         }
     }
  3. 接口指定熔断处理类,fallback

@FeignClient(value = "user-service",fallback = ErrorHander.class)
 public interface HelloAction {
 ​
     @RequestMapping(value = "/hello",method = RequestMethod.GET)
     String hello();
 ​
 }

4.设置超时时间

 #hystrix断路参数配置
 hystrix:
   command:
     default: #default时为默认配置, 相关参数说明在 HystrixCommandProperties
       execution:
         isolation:
           thread:
             timeoutInMilliseconds: 60000

聚合多个Hystrix流

使用的是Netfilx的另外一个项目Turbine

依赖引入

 <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
 </dependency>

启动类开启

@EnableTurbine

添加配置

 turbine:
     app-config: service-1,service-2  #需要注册的服务
     cluster-name-expression: "'default'" #default表示收集集群中的所有聚合流

源码地址:https://github.com/kinglead2012/myblog

原文地址:https://www.cnblogs.com/kinglead/p/14037600.html