天天看點

Spring Cloud之(十五)服務熔斷Hystrix進階

十五、服務熔斷Hystrix進階

我們都知道,當請求失敗、被拒絕、逾時的時候,都會進入到降級方法中,但是進入降級方法并不意味着斷路器已經被打開了,那麼如何才能了解斷路器中的狀态呢?

15.1 Hystrix的監控平台

  • Hystrix的監控平台

    除了實作容錯功能,Hystrix還提供了近乎實時的監控,HystrixCommand和HystrixObservableCommand在執行時,會生成執行結果和運作名額。比如每秒的請求數量,成功數量等。

    這些狀态會暴露在 Actuator 提供的 /health 端點中。隻需為項目添加 spring-boot-actuator 依賴,重新開機項目,通路http://localhost:9021/actuator/hystrix.stream,即可看到實時的監控資料。

    Spring Cloud之(十五)服務熔斷Hystrix進階
    由此可見,Hystrix的監控平台雖然擷取了實時的監控,但是通路 /hystrix.stream 接口擷取的都是以文字形式展示的資訊。
  • 搭建Hystrix DashBoard監控

    Hystrix的監控很難通過文字直覺的展示系統的運作狀态,是以Hystrix官方還提供了基于圖形化DashBoard(儀表闆)監控平台。Hystrix儀表闆可以顯示每個斷路器(被@HystrixCommand注解的方法)的狀态。

    (1)引入依賴

    <!--actuator用于心跳檢查-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <!-- Hystrix DashBoard監控 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
               
    (2)添加EnableHystrixDashboard 注解
    package cn.ebuy.order;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;
    
    @SpringBootApplication
    @EnableFeignClients
    @EnableCircuitBreaker //開啟熔斷器
    //@SpringCloudApplication  此注解是上面三個注解的組合注解
    @EnableHystrixDashboard  //激活儀表盤項目
    public class OrderApplication {
    	/**
    	 * 配置RestTemplate交給spring管理
    	 * 基于Ribbon的服務調用與負載均衡
    	 * @return
    	 */
    	@Bean
    	@LoadBalanced
    	public RestTemplate restTemplate()
    	{
    		return new RestTemplate();
    	}
    
    
    	public static void main(String[] args) {
    		SpringApplication.run(OrderApplication.class,args);
    	}
    }
               

    (3)通路測試

    輸入路徑通路:http://localhost:9021/hystrix

    Spring Cloud之(十五)服務熔斷Hystrix進階
  • 斷路器聚合監控Turbine

    在微服務架構體系中,每個服務都需要配置Hystrix DashBoard監控。如果每次隻能檢視單個執行個體的監控資料,就需要不斷切換監控位址,這顯然很不友善。要想看這個系統的Hystrix Dashboard資料就需要用到Hystrix Turbine。Turbine是一個聚合Hystrix 監控資料的工具,他可以将所有相關微服務的 Hystrix 監控資料聚合到一起,友善使用。引入Turbine後,整個監控系統架構如下:

    Spring Cloud之(十五)服務熔斷Hystrix進階

    建立ebuy-turbine子產品:

    (1)引入依賴

    <!-- 斷路器聚合監控Turbine -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
    </dependency>
    <!-- Hystrix DashBoard監控 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
               
    (2)配置多個微服務的hystrix監控
    server:
      port: 8031 #端口
    spring:
      application:
        name:  ebuy-turbine #服務名稱
    logging:
      level:
        cn.ebuy: DEBUG
    #指定服務注冊中心
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:8000/eureka/,http://127.0.0.1:9000/eureka/
      instance:
        prefer-ip-address: true #使用IP位址注冊
        lease-expiration-duration-in-seconds: 10 #eureka client發送心跳給server端後,續約到期時間(預設90秒)
        lease-renewal-interval-in-seconds: 5 #發送心跳續約間隔
    #指定監控的微服務清單
    turbine:
      app-config: ebuy-order  #要監控的微服務清單
      cluster-name-expression: "'default'"
               
    (3)配置啟動類
    package cn.ebuy.turbine;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
    import org.springframework.cloud.netflix.turbine.EnableTurbine;
    @SpringBootApplication
    @EnableTurbine
    @EnableHystrixDashboard //開啟HystrixDashboard監控平台,并激活Turbine
    public class TurbineApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(TurbineApplication.class,args);
    	}
    }
               

(4)測試

浏覽器通路:http://localhort:8031/hystrix 展示HystrixDashBoard,并在url位置輸入:http://localhost:8031/turbine.stream,動态根據turbine.stream資料展示多個微服務的監控資料。

Spring Cloud之(十五)服務熔斷Hystrix進階

15.2 熔斷器的狀态

熔斷器有三個狀态 CLOSED 、 OPEN 、 HALF_OPEN 熔斷器預設關閉狀态,當觸發熔斷後狀态變更為OPEN ,在等待到指定的時間,Hystrix會放請求檢測服務是否開啟,這期間熔斷器會變為 HALF_OPEN 半開啟狀态,熔斷探測服務可用則繼續變更為 CLOSED 關閉熔斷器。

Spring Cloud之(十五)服務熔斷Hystrix進階
  • Closed:關閉狀态(斷路器關閉),所有請求都正常通路。代理類維護了最近調用失敗的次數,如果某次調用失敗,則使失敗次數加1。如果最近失敗次數超過了在給定時間内允許失敗的門檻值,則代理類切換到斷開(Open)狀态。此時代理開啟了一個逾時時鐘,當該時鐘超過了該時間,則切換到半斷開(Half-Open)狀态。該逾時時間的設定是給了系統一次機會來修正導緻調用失敗的錯誤。
  • Open:打開狀态(斷路器打開),所有請求都會被降級。Hystix會對請求情況計數,當一定時間内失敗請求百分比達到門檻值,則觸發熔斷,斷路器會完全關閉。預設失敗比例的門檻值是50%,請求次數最少不低于20次。
  • Half Open:半開狀态,open狀态不是永久的,打開後會進入休眠時間(預設是5S)。随後斷路器會自動進入半開狀态。此時會釋放1次請求通過,若這個請求是健康的,則會關閉斷路器,否則繼續保持打開,再次進行5秒休眠計時。
Spring Cloud之(十五)服務熔斷Hystrix進階

15.3 熔斷器的隔離政策

微服務使用 Hystrix 熔斷器實作了服務的自動降級,讓微服務具備自我保護的能力,提升了系統的穩定性,也較好的解決雪崩效應。其使用方式目前支援兩種政策:

  • 線程池隔離政策:使用一個線程池來存儲目前的請求,線程池對請求作處理,設定任務傳回處理逾時時間,堆積的請求堆積入線程池隊列。這種方式需要為每個依賴的服務申請線程池,有一定的資源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可将資料存儲到線程池隊裡慢慢處理)
  • 信号量隔離政策:使用一個原子計數器(或信号量)來記錄目前有多少個線程在運作,請求來先判斷計數器的數值,若超過設定的最大線程個數則丢棄改類型的新請求,若不超過則執行計數操作請求來計數器+1,請求傳回計數器-1。這種方式是嚴格的控制線程且立即傳回模式,無法應對突發流量(流量洪峰來臨時,處理的線程超過數量,其他的請求會直接傳回,不繼續去請求依賴的服務)

線程池和型号量兩種政策功能支援對比如下:

Spring Cloud之(十五)服務熔斷Hystrix進階
  1. hystrix.command.default.execution.isolation.strategy : 配置隔離政策
    • ExecutionIsolationStrategy.SEMAPHORE 信号量隔離
    • ExecutionIsolationStrategy.THREAD 線程池隔離
  2. hystrix.command.default.execution.isolation.maxConcurrentRequests : 最大信号量上限

繼續閱讀