Hystrix Fallback 解析

鄒華健可愛多發表於2018-09-29

本文是在已經對 Hystrix 有初步認識的前提下,對 fallback 的一點解析。
引用來自
1.簡書部落格:Hystrix 使用指南(2):Fallback 詳解
作者:編走編想
2.《Spring Cloud 微服務實戰》
作者:翟永超

一、fallback 概述

降級是除了熔斷以外, Hystrix 的另一個重要功能。fallback 是 Hystrix 命令執行失敗時使用的後備方法,用來實現服務的降級處理邏輯。在 HystrixCommand 中可以通過過載 getFallback() 方法來實現服務降級邏輯,Hystrix 會在 run() 執行過程中出現錯誤、超時、執行緒池拒絕、短路熔斷等情況時,執行 getFallback() 方法內的邏輯。

// HystrixCommand 中的 getFallback() 方法,在有後備方法時,可對其過載
protected R getFallback() {
    throw new UnsupportedOperationException("No fallback available.");
}
複製程式碼

二、關於 fallback

(一)以下四種情況會觸發 fallback

1. run() 執行過程中出現錯誤
通常,當 HystrixCommand 的主方法(run()) 中丟擲異常時,便會觸發 getFallback()。除了一個例外 —— HystrixBadRequestException。當丟擲 HystrixBadRequestException,不論當前 Command 是否定義了 getFallback(),都不會觸發,而是向上丟擲異常。

如果實現業務時有一些異常希望能夠向上丟擲,而不是觸發 Fallback 策略,便可以封裝到 HystrixBadRequestException 中。

關於 HystrixBadRequestException另一個需要知道的是,它並不會被 Hystrix 計入失敗。也就是說,不論一個 Command 丟擲多少 HystrixBadRequestException,都不會導致熔斷髮生。

2. run() 執行超時
這種情況也很容易理解,在 Hystrix 中,執行超時也是失敗的一種,所以同樣也會觸發 Fallback。

3. 執行緒池拒絕
執行緒池拒絕指的是 HystrixCommand 所使用的執行緒池沒有足夠的執行緒執行本次呼叫。Hystrix 使用的執行緒池的佇列大小預設為 -1。此時,佇列型別為 SynchronousQueue。當執行緒數不足時,任務會就被拒絕。這種情況也算是一種執行失敗,所以也會出發 Fallback。

4. 斷路器熔斷
當斷路器開啟時,Hystrix 會直接執行 Fallback,而不會執行主方法。

(二)Fallback 的執行執行緒

Hystrix 用來執行 getFallback() 方法所使用的執行緒同執行 run() 方法使用的執行緒是來自同一個執行緒池。

因為 getFallback() 中的邏輯雖然通常為降級策略,但仍為程式功能的一部分,依舊需要使用同主邏輯相同的隔離策略。在預設情況下,即執行緒池隔離。

(三)Fallback 是否受超時時間控制

不受

getFallback() 的執行時間並不受 HystrixCommand 的超時時間的控制。所以,在使用 fallback 機制的時候,要避免 fallback 方法佔用過多的執行緒。

預設情況下,為了避免 getFallback() 方法佔用過多的資源,Hystrix 使用了訊號量 Semaphore 對其進行資源隔離,預設併發度為10。但訊號量的資源隔離的力度是有限的。

如果你在 getFallback() 方法中實現重試邏輯,同時 HystrixCommand 上設定的超時時間是1秒。當熔斷髮生時,因為你在 getFallback() 中再次呼叫同一個方法,且因為 getFallback() 不受超時時間的控制。當 TPS 大於 10 時,儘管主方法沒有耗盡執行緒,但 getFallback() 方法也會把執行緒池耗盡。(假設執行緒池使用預設10的配置)

相關文章