resilience4j(十二):核心模塊Bulkhead源碼之Bulkhead、SemaphoreBulkhead

Bulkhead

resilience4j-SpringBoot2-demo

Bulkhead中文意思:船舶中的隔艙板,將船體分割成多個船艙。把應用系統當成一艘船,那麼應用中不同方法,就對應船裏面不同船艙,船艙可能是單人間,也可能是四人間、八人間、或者大通鋪。船艙容量對應應用中不同方法允許承受的最大併發量。Bulkhead作用是讓一個應用中不同方法互不影響,避免某些方法調用異常危及整個應用。

主要分爲以下幾個模塊:隔離器配置,隔離器註冊,隔離器事件消費者註冊,隔離器狀態及指標,隔離器事件,隔離器事件處理器,隔離器事件消費者。

各模塊間關係

在這裏插入圖片描述

  • BulkheadRegistry通過其實現類InMemoryBulkheadRegistry根據BulkheadConfig創建Bulkhead實例。
  • EventConsumerRegistry通過其實現類DefaultEventConsumerRegistry創建EventConsumer事件消費者。
  • Bulkhead通過其實現類SemaphoreBulkhead控制併發,併發布BulkheadEvent從而被註冊到EventProcessor事件處理器的EventConsumer事件消費者消費。

Bulkhead接口介紹

通過下圖可看出主要依次分爲一下幾個部分:

  • 動態改變隔離配置
  • 隔離請求判斷&完成時操作 (隔離器最核心流程)
  • 獲取對應隔離信息
  • 裝飾器模式提供多個接口、支持lambda表達式。
  • 度量指標
  • 事件發佈&註冊

在這裏插入圖片描述

核心配置

  • maxConcurrentCalls : Bulkhead允許的最大並行執行量。默認:25
  • maxWaitDuration:嘗試進入飽和艙壁時線程阻塞等待的最長時間。默認:0

核心流程圖

Bulkhead核心處理流程如下所示,當請求被拒絕時,拋出BulkheadFullException。並在請求通過、拒絕、完成時,publish 對應 BulkheadEvent。
本文主要講述SemaphoreBulkhead信號量隔離機制,最新版本新增支持了ThreadPoolBulkhead。
在這裏插入圖片描述

BulkheadEvent

隔離器事件,有三種類型。

	   /** 請求被允許通過時,發佈.*/
        CALL_PERMITTED
        /** 請求被允許拒絕時,發佈*/
        CALL_REJECTED,
        /** 處理請求後發佈,無論請求是通過還是被拒絕*/
        CALL_FINISHED;

SemaphoreBulkhead

Bulkhead接口實現類,利用JDK的Semaphore實現併發控制。

從圖中其構造方法可看出,使用的是Semaphore公平模式,即先到先得。
在這裏插入圖片描述

isCallPermitted

    public boolean isCallPermitted() {
		//嘗試獲取信號量,並返回結果
        boolean callPermitted = tryEnterBulkhead();
		//根據獲取結果發佈對應event
        publishBulkheadEvent(
                () -> callPermitted ? new BulkheadOnCallPermittedEvent(name)
                        : new BulkheadOnCallRejectedEvent(name)
        );

        return callPermitted;
    }
    boolean tryEnterBulkhead() {

        boolean callPermitted = false;
        //獲取配置的最大等待時長
        long timeout = config.getMaxWaitTime();

        if (timeout == 0) {
        	//直接嘗試獲取許可
            callPermitted = semaphore.tryAcquire();
        } else {
            try {
               //在對應規定時間內嘗試獲取許可
                callPermitted = semaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS);
            } catch (InterruptedException ex) {
                callPermitted = false;
            }
        }
        return callPermitted;
    }

semaphore.tryAcquire在Semaphore介紹中有介紹,這裏不在敘述。

訂閱消費事件和前面章節CircuitBreaker事件消費類似,不在敘述。

總結:

  • Bulkhead通過JDK中Semaphore(公平模式)實現併發控制。
  • 可在運行時修改Bulkhead配置,同時也可訂閱對應事件。
  • Bulkhead是通過拋出BulkheadFullException方式終止請求調用的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章