1. 程式人生 > >SpringCloud 熔斷器Hystrix

SpringCloud 熔斷器Hystrix

個人學習SpringCloud系列 Hystrix篇

Github Link: https://github.com/panjianlong13/SpringBoot-SpringCloud/tree/master/spring-cloud-hystrix


Hystrix介紹 

Hystrix是什麼

hystrix對應的中文名字是“豪豬”,豪豬周身長滿了刺,能保護自己不受天敵的傷害,代表了一種防禦機制,這與hystrix本身的功能不謀而合,因此Netflix團隊將該框架命名為Hystrix,並使用了對應的卡通形象做作為logo。

在一個分散式系統裡,許多依賴不可避免的會呼叫失敗,比如超時、異常等,如何能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,這個就是Hystrix需要做的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監控等功能,能夠在一個、或多個依賴同時出現問題時保證系統依然可用。

 

Hystrix特性

1.斷路器機制

斷路器很好理解, 當Hystrix Command請求後端服務失敗數量超過一定比例(預設50%), 斷路器會切換到開路狀態(Open). 這時所有請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態一段時間後(預設5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN). Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免傳送大量無效請求影響系統吞吐量, 並且斷路器有自我檢測並恢復的能力.

2.Fallback

Fallback相當於是降級操作. 對於查詢操作, 我們可以實現一個fallback方法, 當請求後端服務出現異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設定的預設值或者來自快取.

3.資源隔離

在Hystrix中, 主要通過執行緒池來實現資源隔離. 通常在使用的時候我們會根據呼叫的遠端服務劃分出多個執行緒池. 例如呼叫產品服務的Command放入A執行緒池, 呼叫賬戶服務的Command放入B執行緒池. 這樣做的主要優點是執行環境被隔離開了. 這樣就算呼叫服務的程式碼存在bug或者由於其他原因導致自己所線上程池被耗盡時, 不會對系統的其他服務造成影響. 但是帶來的代價就是維護多個執行緒池會對系統帶來額外的效能開銷. 如果是對效能有嚴格要求而且確信自己呼叫服務的客戶端程式碼不會出問題的話, 可以使用Hystrix的訊號模式(Semaphores)來隔離資源.

Hystrix設計原則:

資源隔離(執行緒池隔離和訊號量隔離)機制:限制呼叫分散式服務的資源使用,某一個呼叫的服務出現問題不會影響其它服務呼叫。

限流機制:限流機制主要是提前對各個型別的請求設定最高的QPS閾值,若高於設定的閾值則對該請求直接返回,不再呼叫後續資源。

熔斷機制:當失敗率達到閥值自動觸發降級(如因網路故障、超時造成的失敗率真高),熔斷器觸發的快速失敗會進行快速恢復。

降級機制:超時降級、資源不足時(執行緒或訊號量)降級 、執行異常降級等,降級後可以配合降級介面返回託底資料。

雪崩效應

在微服務架構中通常會有多個服務層呼叫,基礎服務的故障可能會導致級聯故障,進而造成整個系統不可用的情況,這種現象被稱為服務雪崩效應。服務雪崩效應是一種因“服務提供者”的不可用導致“服務消費者”的不可用,並將不可用逐漸放大的過程。

如果下圖所示:A作為服務提供者,B為A的服務消費者,C和D是B的服務消費者。A不可用引起了B的不可用,並將不可用像滾雪球一樣放大到C和D時,雪崩效應就形成了。

熔斷器

熔斷器的原理很簡單,如同電力過載保護器。它可以實現快速失敗,如果它在一段時間內偵測到許多類似的錯誤,會強迫其以後的多個呼叫快速失敗,不再訪問遠端伺服器,從而防止應用程式不斷地嘗試執行可能會失敗的操作,使得應用程式繼續執行而不用等待修正錯誤,或者浪費CPU時間去等到長時間的超時產生。熔斷器也可以使應用程式能夠診斷錯誤是否已經修正,如果已經修正,應用程式會再次嘗試呼叫操作。

熔斷器模式就像是那些容易導致錯誤的操作的一種代理。這種代理能夠記錄最近呼叫發生錯誤的次數,然後決定使用允許操作繼續,或者立即返回錯誤。 熔斷器開關相互轉換的邏輯如下圖:

Hytrix工作流程

1、 建立一個 HystrixCommand 或 HystrixObservableCommand 例項

2、 執行方法

3、 快取判斷  檢查快取內是否有對應指令的結果,如果有的話,將快取的結果直接以 Observable 物件的形式返回 

4、 斷路器判斷 如果Circuit Breaker的狀態為開啟狀態,Hystrix將不會執行對應指令,而是直接進入失敗處理狀態

5、 執行緒池、任務佇列、訊號量的檢查 確認是否有足夠的資源執行操作指令。

6、 HystrixObservableCommand.construct() 和 HystrixCommand.run() 如果資源充足,Hystrix將會執行操作指令。

7、 統計斷路器的健康情況 Hystrix會根據記錄的資料來計算失敗比率,一旦失敗比率達到某一閾值將自動開啟Circuit Breaker 

8、 回退

9、 返回成功


Hytrix實戰

1.Eureka Server

application.property

 Enable Eureka Server

 

2.Producer Application

application.property

Hello Controller

/**
 * @ClassName: HelloController
 * @Description: Hello RestController
 * @author Peter Pan
 * @date 2018年12月27日
 *
 */
@RestController
public class HelloController {

	@RequestMapping("/hello")
	public String index(@RequestParam String name) {
		return "hello " + name + "! Sending Message action success";
	}
}

3.Consume Application integrate with Hytrix

application.property

新增fallback屬性,在HelloRemote類新增指定fallback類,在服務熔斷的時候返回fallback類中的內容。

建立回撥函式,HelloRemoteHystrix實現HelloRemote介面

4.測試除錯

依次啟動Eureka Server,Provider Application,Consumer Application

正常呼叫 http://localhost:8081/hello/peter 可以看到Success資訊,此時服務提供方正常工作熔斷器開關沒有開啟

手工停止Producer Application並再次測試,可以看到熔斷器被開啟獲取到Fail資訊