咱們能夠經過增長一個 fallback (回退)方法在hystrix命令實現優雅降級,若是主命令失敗,hystrix能夠獲取一個默認值或者值集合。咱們可能想爲更多的可能失敗的hrstrix命令實現一個回退方法,可是會有如下幾種例外:html
若是設計的hrstrix命令是執行一個寫操做而不是返回一個結果(這個寫操做在 HystrixCommand
一般返回 void,在 HystrixObservableCommand
返回一個空的可觀察者),此場景下執行回退方法沒有什麼意義,若是寫操做失敗,服務方應該是但願告知調用方,讓調用方再進一步處理。java
若是Hystrix命令正在填充一個緩存,或者生成一個報告,或者作任何離線計算。若是發生錯誤,一般應該將錯誤告知調用方,讓調用方作進一步處理,而不該該發送一個默認的響應。git
若是命令執行異常,不管Hystrix命令是否有回退方法,hystrix命令狀態、斷路器/度量器都會更新爲此條命令失敗。github
在一個普通的HystrixCommand
中經過重寫 getFallback()
方法實現一個回退方法,好比 run()
方法有異常, hystrix會爲全部類型的異常執行回退方法,好比 超時、線程池或信號量拒絕,以及斷路器短路。 包含回退方法的示例以下:緩存
public class HystrixHelloWorldFallback extends HystrixCommand<String> { private final String name; public HystrixHelloWorldFallback(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { throw new RuntimeException("模擬異常!"); } @Override protected String getFallback() { return "Hello Failure " + name + "!"; } }
以上代碼中 run()方法永遠會出現異常,調用者永遠接收到的是 getFallback()方法返回的值,不會接收到異常,如下單元測試成功: 單元測試
@Test public void testSynchronous() { assertEquals("Hello Failure World!", new HystrixHelloWorldFallback("World").execute()); assertEquals("Hello Failure Bob!", new HystrixHelloWorldFallback("Bob").execute()); }
對於HystrixObservableCommand,須要經過重寫 resumeWithFallback
方法,若是執行失敗了,它就會從主觀察者接管失敗返回第二可觀察者。這裏須要注意的是,已經發送的一個或多個數據項以後,可觀察者可能會失敗,因此回退方法不該該假設它會發送觀察者看到的惟一值。測試
在內部,Hystrix使用RxJava的 onerrorerrorenext操做符,在發生錯誤時,在主觀察者和回退之間無縫切換。this
@adrianb11 友好的提供了一個hystrix 超時回退時操做的時序圖,點擊查看spa
從run()方法拋出的除 HystrixBadRequestException
異常外的全部異常,會統計異常次數、觸發回退方法和短路邏輯。
能夠將想拋出的異常包裝到 HystrixBadRequestException
經過 getCause()
方法查詢它 ,HystrixBadRequestException
適用於報告非法參數或非系統故障的場景,這些錯誤不該該與失敗的指標相違背,也不該該觸發回退邏輯。
在 HystrixObservableCommand
例子中,不可恢復的錯誤經過 產生 Observable
的 onError
通知, 而降低是經過回到第二個可觀察到的,即Hystrix經過您實現的恢復的回退方法得到的, 降級是降低到經過 Hystrix實現 resumeWithFallback
方法得到的第二個可觀察完成的。
失敗類型 | 異常類 | 異常緣由 | 是否執行回退 |
---|---|---|---|
失敗 | HystrixRuntimeException |
潛在異常(用戶控制) | 執行 |
超時 | HystrixRuntimeException |
j.u.c.TimeoutException |
執行 |
短路 | HystrixRuntimeException |
j.l.RuntimeException |
執行 |
線程池異常 | HystrixRuntimeException |
j.u.c.RejectedExecutionException |
執行 |
信號量拒絕 | HystrixRuntimeException |
j.l.RuntimeException |
執行 |
失敗請求 | HystrixBadRequestException |
underlying exception (user-controlled) | 不執行 |
轉帖請註明原貼地址 : https://my.oschina.net/u/2342969/blog/1814990