26 服務熔斷Hystrix高階

我們知道,當請求失敗,被拒絕,超時的時候,都會進入到降級方法中。但進入降級方法並不意味著斷 路器已經被開啟。那麼如何才能瞭解斷路器中的狀態呢?

Hystrix的監控平臺

除了實現容錯功能,Hystrix還提供了近乎實時的監控,HystrixCommand和 HystrixObservableCommand在執行時,會生成執行結果和執行指標。比如每秒的請求數量,成功數 量等。這些狀態會暴露在Actuator提供的/health端點中。只需為專案新增 spring-boot-actuator 依 賴,重啟專案,訪問http://localhost:9001/actuator/hystrix。stream ,即可看到實時的監控資料。

26 服務熔斷Hystrix高階

搭建Hystrix DashBoard監控

剛剛討論了Hystrix的監控,但訪問/hystrix。stream介面獲取的都是已文字形式展示的資訊。很難透過文 字直觀的展示系統的執行狀態,所以Hystrix官方還提供了基於圖形化的DashBoard(儀表板)監控平 臺。Hystrix儀表板可以顯示每個斷路器(被@HystrixCommand註解的方法)的狀態。

(1)匯入依賴

org。springframework。bootspring-boot-starter-actuatororg。springframework。cloudspring-cloud-starter-netflix-hystrixorg。springframework。cloudspring-cloud-starter-netflix-hystrix-dashboard

(2)新增EnableHystrixDashboard 註解

在啟動類使用@EnableHystrixDashboard註解啟用儀表盤專案

@EnableHystrixDashboardpublic class OrderApplication {public static void main(String[] args) {SpringApplication。run(OrderApplication。class, args);}}

(3)訪問測試

26 服務熔斷Hystrix高階

輸入監控斷點展示監控的詳細資料

26 服務熔斷Hystrix高階

斷路器聚合監控Turbine

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

26 服務熔斷Hystrix高階

(1) 搭建TurbineServer

建立工程 shop_hystrix_turbine 引入相關座標

org。springframework。cloudspring-cloud-starter-netflix-turbineorg。springframework。cloudspring-cloud-starter-netflix-hystrixorg。springframework。cloudspring-cloud-starter-netflix-hystrix-dashboard

(2) 配置多個微服務的hystrix監控

在application。yml的配置檔案中開啟turbine並進行相關配置

server:port: 8031spring:application:name: microservice-hystrix-turbineeureka:client:service-url:defaultZone: http://localhost:8761/eureka/instance:prefer-ip-address: trueturbine:# 要監控的微服務列表,多個用,分隔appConfig: shop-service-orderclusterNameExpression: “‘default’”

eureka相關配置 : 指定註冊中心地址

turbine相關配置:指定需要監控的微服務列表

turbine會自動的從註冊中心中獲取需要監控的微服務,並聚合所有微服務中的 /hystrix。stream 資料

(3)配置啟動類

@SpringBootApplication@EnableTurbine@EnableHystrixDashboardpublic class TurbineServerApplication {public static void main(String[] args) { SpringApplication。run(TurbineServerApplication。class, args);}}

作為一個獨立的監控專案,需要配置啟動類,開啟HystrixDashboard監控平臺,並激活Turbine

(4) 測試

26 服務熔斷Hystrix高階

熔斷器的狀態

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

26 服務熔斷Hystrix高階

Closed:關閉狀態(斷路器關閉),所有請求都正常訪問。代理類維護了最近呼叫失敗的次數, 如果某次呼叫失敗,則使失敗次數加1。如果最近失敗次數超過了在給定時間內允許失敗的閾值, 則代理類切換到斷開(Open)狀態。此時代理開啟了一個超時時鐘,當該時鐘超過了該時間,則切 換到半斷開(Half-Open)狀態。該超時時間的設定是給了系統一次機會來修正導致呼叫失敗的錯 誤。

Open:開啟狀態(斷路器開啟),所有請求都會被降級。Hystix會對請求情況計數,當一定時間 內失敗請求百分比達到閾值,則觸發熔斷,斷路器會完全關閉。預設失敗比例的閾值是50%,請求 次數最少不低於20次。

Half Open:半開狀態,open狀態不是永久的,開啟後會進入休眠時間(預設是5S)。隨後斷路 器會自動進入半開狀態。此時會釋放1次請求透過,若這個請求是健康的,則會關閉斷路器,否則 繼續保持開啟,再次進行5秒休眠計時。

為了能夠精確控制請求的成功或失敗,我們在 shop_service_product 的呼叫業務中加入一段邏輯:

@GetMapping(“/{id}”)public Product findById(@PathVariable Long id) {if(id !=1 ) {throw new RuntimeException(“太忙了”);}return productService。findById(id);}

這樣如果引數是id為1,一定失敗,其它情況都成功。

我們準備兩個請求視窗:

一個請求:http://localhost:8080/consumer/1,註定失敗 一

個請求:http://localhost:8080/consumer/2,肯定成功

熔斷器的預設觸發閾值是20次請求,不好觸發。休眠時間時5秒,時間太短,不易觀察,為了測試方 便,我們可以透過配置修改熔斷策略:

circuitBreaker。requestVolumeThreshold=5circuitBreaker。sleepWindowInMilliseconds=10000circuitBreaker。errorThresholdPercentage=50

解讀:

requestVolumeThreshold:觸發熔斷的最小請求次數,預設20

errorThresholdPercentage:觸發熔斷的失敗請求最小佔比,預設50%

sleepWindowInMilliseconds:熔斷多少秒後去嘗試請求

當我們瘋狂訪問id為1的請求時(超過10次),就會觸發熔斷。斷路器會埠,一切請求都會被降級處 理。

此時你訪問id為2的請求,會發現返回的也是失敗,而且失敗時間很短,只有20毫秒左右:

26 服務熔斷Hystrix高階

熔斷器的隔離策略

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

執行緒池隔離策略:使用一個執行緒池來儲存當前的請求,執行緒池對請求作處理,設定任務返回處理超 時時間,堆積的請求堆積入執行緒池佇列。這種方式需要為每個依賴的服務申請執行緒池,有一定的資 源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可將資料儲存到執行緒池隊裡慢慢處 理)

訊號量隔離策略:使用一個原子計數器(或訊號量)來記錄當前有多少個執行緒在執行,請求來先判 斷計數器的數值,若超過設定的最大執行緒個數則丟棄改型別的新請求,若不超過則執行計數操作請 求來計數器+1,請求返回計數器-1。這種方式是嚴格的控制執行緒且立即返回模式,無法應對突發 流量(流量洪峰來臨時,處理的執行緒超過數量,其他的請求會直接返回,不繼續去請求依賴的服 務):

執行緒池和型號量兩種策略功能支援對比如下:

26 服務熔斷Hystrix高階