1. 程式人生 > 實用技巧 >十一、一文搞定spring cloud重要成員--Hystrix(斷路器)

十一、一文搞定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