實踐 | Sentinel 擴充套件性設計
Sentinel" rel="nofollow,noindex" target="_blank">Sentinel 提供多樣的 SPI 介面用於提供擴充套件的能力。使用者可以在用同一個 sentinel-core 的基礎上自行擴充套件介面實現,從而可以方便地給 Sentinel 新增自定義的邏輯。
初始化邏輯擴充套件機制
為了統一初始化的流程,我們抽象出了 InitFunc
介面代表 Sentinel 的一些初始化邏輯,如:
我們可以通過註解設定 InitFunc
執行的優先順序。當應用首次訪問資源時,註冊的初始化函式會依次執行。若希望手動提前觸發初始化,可以在相應的位置(如 Spring Bean)呼叫 InitExecutor.doInit()
函式,重複呼叫只會執行一次。
Slot Chain 擴充套件機制
Sentinel 內部是通過一系列的 slot 組成的 slot chain 來完成各種功能的,包括構建呼叫鏈、呼叫資料統計、規則檢查等。各個 slot 之間的順序非常重要。Sentinel 將 SlotChainBuilder
作為 SPI 介面進行擴充套件,使得 Slot Chain 具備了擴充套件的能力。使用者可以自行加入自定義的 slot 並編排 slot 間的順序,從而可以給 Sentinel 新增自定義的功能。
比如我們想要在請求 pass 後記錄當前的 context 和資源資訊,則可以實現一個簡單的 slot:
public class DemoSlot extends AbstractLinkedProcessorSlot<DefaultNode> { @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, Object... args) throws Throwable { System.out.println("Current context: " + context.getName()); System.out.println("Current entry resource: " + context.getCurEntry().getResourceWrapper().getName()); fireEntry(context, resourceWrapper, node, count, args); } @Override public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) { System.out.println("Exiting for entry on DemoSlot: " + context.getCurEntry().getResourceWrapper().getName()); fireExit(context, resourceWrapper, count, args); } }
然後實現一個 SlotChainBuilder
,可以在 DefaultSlotChainBuilder
的基礎上將我們新的 slot 新增到鏈的尾部(當然也可以不用 DefaultSlotChainBuilder,自由組合現有的 slot):
package com.alibaba.csp.sentinel.demo.slot; public class DemoSlotChainBuilder implements SlotChainBuilder { @Override public ProcessorSlotChain build() { ProcessorSlotChain chain = new DefaultSlotChainBuilder().build(); chain.addLast(new DemoSlot()); return chain; } }
最後在 resources/META-INF/services
目錄下的 SPI 配置檔案 com.alibaba.csp.sentinel.slotchain.SlotChainBuilder
中新增上實現的 SlotChainBuilder 的類名即可生效:
# Custom slot chain builder com.alibaba.csp.sentinel.demo.slot.DemoSlotChainBuilder
Sentinel 的熱點限流模組就是利用了 Slot Chain 的擴充套件機制來將熱點限流功能新增到原有的功能鏈中。
StatisticSlot Callback
之前 StatisticSlot
裡面包含了太多的邏輯,像普通 QPS 和 熱點引數 QPS 的 addPass/addBlock 等邏輯統計都在 StatisticSlot
裡面,各個邏輯都雜糅在一起,不利於擴充套件。因此有必要為 StatisticSlot
抽象出一系列的 callback,從而使 StatisticSlot 具備基本的擴充套件能力,並將一系列的邏輯從 StatisticSlot
解耦出來,更為清晰。目前 Sentinel 提供了兩種 callback:
-
ProcessorSlotEntryCallback
:包含onPass
和onBlocked
兩個回撥函式,分別對應請求通過 StatisticSlot 和請求被 blocked 的時候執行。 -
ProcessorSlotExitCallback
:包含onExit
回撥函式,當請求經 StatisticSlot exit 的時候執行。
使用者只需將實現的 callback 註冊到 StatisticSlotCallbackRegistry
即可生效。
動態規則源
Sentinel 的 動態規則資料來源 用於從外部的儲存中讀取及寫入規則。Sentinel 將動態規則資料來源劃分為兩種型別:讀資料來源( ReadableDataSource
)和寫資料來源( WritableDataSource
),從而使不同型別的資料來源職責更加清晰:
- 讀資料來源僅負責監聽或輪詢讀取遠端儲存的變更。
- 寫資料來源僅負責將規則變更寫入到規則源中。
我們只需要自己實現動態規則源,然後將其註冊至對應的 RuleManager 上,這樣就可以實時地配置規則並進行拉取/推送了。註冊動態規則源時可以藉助 Sentinel 的 InitFunc
SPI 在初始化時自動註冊。
Transport 擴充套件機制
CommandHandler
歡迎關注“阿里巴巴中介軟體”,加入中介軟體開發者群,與技術同行。