sentinel--核心原理篇

本篇內容主要主要從理論及源碼角度介紹sentinel降級和限流的核心原理。若是有對sentinel功能不瞭解的能夠先閱讀下《sentinel--初級使用篇》。  node

一、核心骨架介紹

Sentinel 的核心骨架,將不一樣的 Slot 按照順序串在一塊兒(責任鏈模式),從而將不一樣的功能(限流、降級、系統保護)組合在一塊兒。slot chain 其實能夠分爲兩部分:統計數據構建部分(statistic)和判斷部分(rule checking)。核心結構以下圖:  緩存

目前是一個資源對應一個Slot 鏈。

二、核心骨架構架過程

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 實例。它的做用是爲了區分調用鏈路,標識調用入口。  app

②處代碼很是關鍵(lookProcessChain(resourceWrapper) 這個方法),內部實現以下  框架

經過SPI機制將META-INFO/servcie下配置好的默認責任鏈構造這加載出來,而後調用其builder()方法進行構建調用鏈  oop

責任鏈一樣是由spi機制加載出來的,上面的加載只會在第一次使用的時候加載,而後緩存到內從後,之後直接取便可。其中責任鏈的構架過程相似有現行鏈表的構建過程,具體以下圖,這裏就不在過多贅述。ui

咱們前面說了,責任鏈實例和 resource name 相關,和線程無關,因此當處理同一個 resource 的時候,會進入到同一個 NodeSelectorSlot 實例中。該節點主要處理的是:不一樣的 context name,同一個 resource name 的狀況。以下面的兩段代碼: 線程

接下來,咱們來到了 ClusterBuilderSlot 這一環,這一環的主要做用是構建 ClusterNode。這裏不貼源碼,根據上面的樹,而後在通過該類的處理之後,咱們能夠得出下面這棵樹:code

從上圖能夠看到,對於每個resource,這裏會對應一個 ClusterNode 實例,若是不存在,就建立一個實例。這個 ClusterNode 很是有用,由於咱們就是使用它來作數據統計的。好比 getUserInfo 這個接口,因爲從不一樣的 context name 中開啓調用鏈,它有多個 DefaultNode 實例,可是隻有一個 ClusterNode,經過這個實例,咱們能夠知道這個接口如今的 QPS 是多少。另外,這個類還處理了 origin 不是默認值的狀況:  blog

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 中是不展現的,畢竟也沒什麼用。到此爲止咱們的核心骨架就建立完成了。  

相關文章
相關標籤/搜索