執行流程
建立command
執行command
request cache
短路器,如果打開了,fallback降級機制
1 fallback降級機制
Hystrix調用各種接口,或者通路外部依賴,MySQL,Redis,ZooKeeper,Kafka等,出現任何異常的情況,比如通路報錯
對每個外部依賴,無論是服務接口,中間件,資源隔離,對外部依賴隻能用一定量的資源去通路,線程池/信号量等資源池已滿
reject通路外部依賴的時候,通路時間過長,可能就會導緻逾時,報一個TimeoutException異常,timeout
對外部依賴的東西通路的時候出現了異常,發送異常事件到短路器中去進行統計
如果短路器發現異常事件的占比達到了一定比例,直接開啟短路(circuit breaker)
上述四種情況,都會去調用fallback降級機制
fallback,你之前都是必須去調用外部的依賴接口,或者從MySQL中去查詢資料的,但是為了避免說可能外部依賴會有故障
2 實作方案
2.1 純記憶體資料
可以在記憶體中維護一個ECache,作為基于LRU自動清理的純記憶體緩存,資料也可放入緩存
如果說外部依賴有異常,fallback這裡,直接嘗試從ECache中擷取資料
2.2 預設值
本來你是從mysql,redis,或者其他任何地方去擷取資料的,擷取調用其他服務的接口的,結果人家故障了,人家挂了,fallback,可以傳回一個預設值
run()抛出異常,逾時,線程池或信号量滿了,或短路了,都會調用fallback機制
案例
現在有個商品資料,brandId,品牌,假設拿到了一個商品資料以後,用brandId再調用一次請求,到其他的服務去擷取品牌的最新名稱
假如那個品牌服務挂掉了,那麼我們可以嘗試本地記憶體中,會保留一份時間比較過期的一份品牌資料,有些品牌沒有,有些品牌的名稱過期了,調用品牌服務失敗了,fallback降級就從本地記憶體中擷取一份過期的資料,先湊合着用着
public class CommandHelloFailure extends HystrixCommand<String> {
private final String name;
public CommandHelloFailure(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
throw new RuntimeException("this command always fails");
}
@Override
protected String getFallback() {
return "Hello Failure " + name + "!";
}
}
@Test
public void testSynchronous() {
assertEquals("Hello Failure World!", new CommandHelloFailure("World").execute());
}
HystrixObservableCommand,是實作resumeWithFallback方法
2、fallback.isolation.semaphore.maxConcurrentRequests
這個參數設定了HystrixCommand.getFallback()最大允許的并發請求數量,預設值是10,也是通過semaphore信号量的機制去限流
如果超出了這個最大值,那麼直接被reject
HystrixCommandProperties.Setter()
.withFallbackIsolationSemaphoreMaxConcurrentRequests(int value)