天天看點

大廠網際網路電商基于本地緩存的fallback降級機制1 fallback降級機制2 實作方案

執行流程

建立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)