本篇內容主要主要從理論及原始碼角度介紹sentinel降級和限流的核心原理,如果有對sentinel功能不了解的可以先閱讀下《sentinel--初級使用篇》,
1、核心骨架介紹
Sentinel 的核心骨架,將不同的 Slot 按照順序串在一起(責任鏈模式),從而將不同的功能(限流、降級、系統保護)組合在一起,slot chain 其實可以分為兩部分:統計資料構建部分(statistic)和判斷部分(rule checking),核心結構如下圖:

目前是一個資源對應一個Slot 鏈,
2、核心骨架構架程序
Entry entry = null;
try {
entry = SphU.entry(KEY);
throw new RuntimeException("oops");
}catch (Throwable t) {
bizException.incrementAndGet();
// It\'s required to record exception here manually.
Tracer.traceEntry(t, entry);
} finally {
total.addAndGet(1);
if (entry != null) {
entry.exit();
}
}
先貼一段sentinel的基本使用用法,然后一路往下跟到下圖:

①段代碼會生成下面這樣一顆樹

這里的原始碼非常簡單,如果我們從來不顯式呼叫 ContextUtil#enter 方法的話,那 root 就只有一個 default 子節點,context 很好理解,它代表執行緒執行的背景關系,在各種開源框架中都有類似的語意,在 Sentinel 中,我們可以看到,對于一個新的 context name,Sentinel 會往樹中添加一個 EntranceNode 實體,它的作用是為了區分呼叫鏈路,標識呼叫入口,
②處代碼非常關鍵(lookProcessChain(resourceWrapper) 這個方法),內部實作如下

通過SPI機制將META-INFO/servcie下配置好的默認責任鏈構造這加載出來,然后呼叫其builder()方法進行構建呼叫鏈


責任鏈同樣是由spi機制加載出來的,上面的加載只會在第一次使用的時候加載,然后快取到內從后,以后直接取即可,其中責任鏈的構架程序類似有現行鏈表的構建程序,具體如下圖,這里就不在過多贅述,



我們前面說了,責任鏈實體和 resource name 相關,和執行緒無關,所以當處理同一個 resource 的時候,會進入到同一個 NodeSelectorSlot 實體中,該節點主要處理的是:不同的 context name,同一個 resource name 的情況,如下面的兩段代碼:
接下來,我們來到了 ClusterBuilderSlot 這一環,這一環的主要作用是構建 ClusterNode,這里不貼原始碼,根據上面的樹,然后在經過該類的處理以后,我們可以得出下面這棵樹:

從上圖可以看到,對于每一個resource,這里會對應一個 ClusterNode 實體,如果不存在,就創建一個實體,這個 ClusterNode 非常有用,因為我們就是使用它來做資料統計的,比如 getUserInfo 這個介面,由于從不同的 context name 中開啟呼叫鏈,它有多個 DefaultNode 實體,但是只有一個 ClusterNode,通過這個實體,我們可以知道這個介面現在的 QPS 是多少,另外,這個類還處理了 origin 不是默認值的情況:
if (!"".equals(context.getOrigin())) {
Node originNode = node.getClusterNode().getOrCreateOriginNode(context.getOrigin());
context.getCurEntry().setOriginNode(originNode);
}
我們可以看到,當設定了 origin 的時候,會額外生成一個 StatisticsNode 實體,掛在 ClusterNode 上,我們把前面的代碼改改,看紅色部分:

我們的 getUserInfo 接收到了來自 application-a 和 application-b 兩個應用的請求,那么樹會變成下面這樣:

它的作用是用來統計從 application-a 過來的訪問 getUserInfo 這個介面的資訊,目前這個資訊在 dashboard 中是不展示的,畢竟也沒什么用,到此為止我們的核心骨架就創建完成了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/228913.html
標籤:架構設計
上一篇:sentinel--初級使用篇
