天天看點

Ali sentinel 代碼分析-基礎及概念

阿裡Sentinel 基本概念主要包括下圖内容:

總體說明

Ali sentinel 代碼分析-基礎及概念

從定義和運作兩種态勢,可以分為定義态:

  • rule,規則,每個規則定義都關聯一個資源名稱,一個資源可以定義多個rule
  • ruleManager ,規則管理
  • slot,承載規則的卡槽
  • Chain,多個slot組成的鍊,在老版本 Chain是hard code寫死的,1.8.1使用order 來定義,便于加入自定義slot

運作态:

  • Entry :入口,入口會指定資源名稱
  • Chain及slot: 執行鍊
  • Context: 上下文,貫穿整個執行過程
  • Node: 保留各種資料,如一定時間内的qps
  • Metric:各種名額,儲存在node上,注意node還有非metric資料
  • Resource: 被Entry保護的資源,可以通俗了解為所有rule通過後要執行的代碼

Resource

可以了解為Entry(後面會講)擷取成功要要執行的方法或者代碼 ,一般和Entry綁定在一起,如:

try (Entry entry = SphU.entry("HelloWorld")) {
            // 被保護的邏輯
            System.out.println("hello world");
	} catch (BlockException ex) {
            // 處理被流控的邏輯
	    System.out.println("blocked!");
	}
           

或者annotation寫法:

@SentinelResource("HelloWorld")
public void helloWorld() {
    // 資源中的邏輯
    System.out.println("hello world");
}
  
           

以上代碼中的"HelloWorld" 被稱為資源名稱,用于關聯下面提到的slot及chain,也可以了解為通過resource name進行規則關聯。

目前隻有String和method兩種resource,對應的類定義資訊如下:

28   * @author qinan.qn
   29   */
   30: public class MethodResourceWrapper extends ResourceWrapper {
   31  
   32      private final transient Method method;

 
   25   * @author jialiang.linjl
   26   */
   27: public class StringResourceWrapper extends ResourceWrapper {
   28  
   29      public StringResourceWrapper(String name, EntryType e) {
           

Entry

以下為Entry的官方說法:

每一次資源調用都會建立一個 Entry。Entry 包含了資源名、curNode(目前統計節點)、originNode(來源統計節點)等資訊。

CtEntry 為普通的 Entry,在調用 SphU.entry(xxx) 的時候建立。特性:Linked entry within current context(内部維護着 parent 和 child)

需要注意的一點:CtEntry 構造函數中會做調用鍊的變換,即将目前 Entry 接到傳入 Context 的調用鍊路上(setUpEntryFor)。

資源調用結束時需要 entry.exit()。exit 操作會過一遍 slot chain exit,恢複調用棧,exit context 然後清空 entry 中的 context 防止重複調用。

通俗來說,Entry就是進入sentinel的一系列資料(如CPU、QPS)擷取及規則判斷,如果這些規則判斷都通過了,就執行資源函數或者代碼。

Entry的執行過程就對應則一個或者多個規則集合體,有兩個實作類:

SphU.entry() 擷取失敗傳回異常
SphO.entry()  傳回true或者false
           

這兩個類的最終實作都是通過類CtSph實作的,可以參考如下代碼

public static boolean entry(String name, EntryType trafficType, int batchCount, Object... args) {
        try {
            Env.sph.entry(name, trafficType, batchCount, args);
        } catch (BlockException e) {
            return false;
        } catch (Throwable e) {
            RecordLog.warn("SphO fatal error", e);
            return true;
        }
        return true;
    }

public class Env {

    public static final Sph sph = new CtSph();

    static {
        // If init fails, the process will exit.
        InitExecutor.doInit();
    }

}
           

chain及slot

沒有Entry在執行過程會去尋找對應的Chain

ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) {
        ProcessorSlotChain chain = chainMap.get(resourceWrapper);
        if (chain == null) {
            synchronized (LOCK) {
                chain = chainMap.get(resourceWrapper);
                if (chain == null) {
                    // Entry size limit.
                    if (chainMap.size() >= Constants.MAX_SLOT_CHAIN_SIZE) {
                        return null;
                    }

                    chain = SlotChainProvider.newSlotChain();
                    Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>(
                        chainMap.size() + 1);
                    newMap.putAll(chainMap);
                    newMap.put(resourceWrapper, chain);
                    chainMap = newMap;
                }
            }
        }
        return chain;
    }
           

然後執行Chain上的slot(資料擷取或者檢測類),預設chain 的build 類是com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder

可以參考sentinel-demo-slot-chain-spi 進行修改

sentinel 自帶的主要slot如下

  • NodeSelectorSlot 負責收集資源的路徑,并将這些資源的調用路徑,以樹狀結構存儲起來,用于根據調用路徑來限流降級;
  • ClusterBuilderSlot 則用于存儲資源的統計資訊以及調用者資訊,例如該資源的 RT, QPS, thread count等等,這些資訊将用作為多元度限流,降級的依據;
  • StatisticSlot 則用于記錄、統計不同緯度的 runtime 名額監控資訊
  • FlowSlot 則用于根據預設的限流規則以及前面 slot 統計的狀态,來進行流量控制;
  • AuthoritySlot則根據配置的黑白名單和調用來源資訊,來做黑白名單控制;
  • DegradeSlot 則通過統計資訊以及預設的規則,來做熔斷降級
  • SystemSlot 則通過系統的狀态,例如 load1 等,來控制總的入口流量;

Rule

Chain是内部執行,外部不能直接定義,外部定義是通過rules模式來實作的,可以參考sentinel-demo-basic 下的這四個子目錄下的代碼

Ali sentinel 代碼分析-基礎及概念

這四個目錄對應四中規則:

  • DegradeRule
  • AuthorityRule
  • FlowRule
  • SystemRule

一個資源可以有以上4種規則中的多種進行合并判斷。

Context

context中維護着目前調用鍊的中繼資料

SphU.entry() 或 SphO.entry() 都需要在一個 context 中執行,如果沒有目前執行時還沒有 context,那麼架構會使用預設的 context,預設的 context 是通過 MyContextUtil.myEnter() 建立的

Node

Node 中儲存了資源的實時統計資料,例如:passQps,blockQps,rt等實時資料。正是有了這些統計資料後, Sentinel 才能進行限流、降級等一系列的操作。

Metric

Metric 是 Sentinel 中用來進行實時資料統計的度量接口,node就是通過metric來進行資料統計的。而metric本身也并沒有統計的能力,他也是通過Window來進行統計的。

繼續閱讀