摘要: Sentinel 提供多樣的 SPI 接口用於提供擴展的能力。用戶能夠在用同一個 sentinel-core 的基礎上自行擴展接口實現,從而能夠方便地給 Sentinel 添加自定義的邏輯。 初始化邏輯擴展機制 爲了統一初始化的流程,咱們抽象出了 InitFunc 接口表明 Sentinel 的一些初始化邏輯,如: 註冊動態規則源(示例) 註冊 StatisticSlot 回調函數(示例) 啓動 Command Center 初始化心跳發送 咱們能夠經過註解設置 InitFunc 執行的優先級。node
Sentinel 提供多樣的 SPI 接口用於提供擴展的能力。用戶能夠在用同一個 sentinel-core 的基礎上自行擴展接口實現,從而能夠方便地給 Sentinel 添加自定義的邏輯。網絡
初始化邏輯擴展機制
爲了統一初始化的流程,咱們抽象出了 InitFunc 接口表明 Sentinel 的一些初始化邏輯,如:app
註冊動態規則源(示例)
註冊 StatisticSlot 回調函數(示例)
啓動 Command Center
初始化心跳發送
咱們能夠經過註解設置 InitFunc 執行的優先級。當應用首次訪問資源時,註冊的初始化函數會依次執行。若但願手動提早觸發初始化,能夠在相應的位置(如 Spring Bean)調用 InitExecutor.doInit() 函數,重複調用只會執行一次。ide
Slot Chain 擴展機制
Sentinel 內部是經過一系列的 slot 組成的 slot chain 來完成各類功能的,包括構建調用鏈、調用數據統計、規則檢查等。各個 slot 之間的順序很是重要。Sentinel 將 SlotChainBuilder 做爲 SPI 接口進行擴展,使得 Slot Chain 具有了擴展的能力。用戶能夠自行加入自定義的 slot 並編排 slot 間的順序,從而能夠給 Sentinel 添加自定義的功能。函數
好比咱們想要在請求 pass 後記錄當前的 context 和資源信息,則能夠實現一個簡單的 slot:ui
public class DemoSlot extends AbstractLinkedProcessorSlot<DefaultNode> {spa
@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):code
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 的類名便可生效:
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 擴展機制CommandCenter 可擴展:用戶能夠用不一樣的網絡協議或不一樣的庫來實現 Transport API Server。HeartbeatSender 可擴展:用戶能夠用不一樣的網絡協議和心跳策略來實現心跳發送(上報到控制檯)。CommandHandler 可擴展:用戶能夠自行實現 CommandHandler 並註冊到 SPI 配置文件中來爲 CommandCenter 添加自定義的命令。