Sentinel核心原始碼決議
Sentinel是分布式系統的防御系統,以流量為切入點,通過動態設定的流量控制、服務熔斷等手段達到
保護系統的目的,通過服務降級增強服務被拒后用戶的體驗,
一、Sentinel作業原理
1 架構圖決議
若要讀懂Sentinel原始碼,則必須要搞明白官方給出的Sentinel的架構圖,
微服務框架核心原始碼深度決議<<大廠學院完結>>
Sentinel的核心骨架是ProcessorSlotChain,其將不同的 Slot 按照順序串在一起(責任鏈模式),從而將不同的功能組合在一起(限流、降級、系統保護),系統會為每個資源創建一套SlotChain,
2 SPI機制
Sentinel槽鏈中各Slot的執行順序是固定好的,但并不是絕對不能改變的,Sentinel將ProcessorSlot 作為 SPI 介面進行擴展,使得 SlotChain 具備了擴展能力,用戶可以自定義Slot并編排Slot 間的順序,
3 Slot簡介
NodeSelectorSlot
負責收集資源的路徑,并將這些資源的呼叫路徑,以樹狀結構存盤起來,用于根據呼叫路徑來限流降,
ClusterBuilderSlot
用于存盤資源的統計資訊以及呼叫者資訊,例如該資源的 RT, QPS, thread count,Block count,Exception count 等等,這些資訊將用作為多維度限流,降級的依據,簡單來說,就是用于構建ClusterNode,
StatisticSlot
用于記錄、統計不同緯度的 runtime 指標監控資訊,
ParamFlowSlot
對應熱點流控,
FlowSlot
用于根據預設的限流規則以及前面 slot 統計的狀態,來進行流量控制,對應流控規則,
AuthoritySlot
根據配置的黑白名單和呼叫來源資訊,來做黑白名單控制,對應授權規則,
DegradeSlot
通過統計資訊以及預設的規則,來做熔斷降級,對應降級規則,
SystemSlot
通過系統的狀態,例如 load1 等,來控制總的入口流量,對應系統規則,
4 Context簡介
Context是對資源操作的背景關系,每個資源操作必須屬于一個Context,如果代碼中沒有指定Context,則會創建一個name為sentinel_default_context的默認Context,一個Context生命周期中可以包含多個資源操作,Context生命周期中的最后一個資源在exit()時會清理該Conetxt,這也就意味著這個Context生命周期結束了,
5 Context代碼
// 創建一個來自于appA訪問的Context,
// entranceOne為Context的name
ContextUtil.enter("entranceOne", "appA");
// Entry就是一個資源操作物件
Entry resource1 = null;
Entry resource2 = null;
try {
// 獲取資源resource1的entry
resource1 = SphU.entry("resource1");
// 代碼能走到這里,說明當前對資源resource1的請求通過了流控
// 對資源resource1的相關業務處理,,,
// 獲取資源resource2的entry
resource2 = SphU.entry("resource2");
// 代碼能走到這里,說明當前對資源resource2的請求通過了流控
// 對資源resource2的相關業務處理,,,
} catch (BlockException e) {
// 代碼能走到這里,說明請求被限流,
// 這里執行降級處理
} finally {
if (resource1 != null) {
resource1.exit();
}
if (resource2 != null) {
resource2.exit();
}
}
// 釋放Context
ContextUtil.exit();
// --------------------------------------------------------
// 創建另一個來自于appA訪問的Context,
// entranceTwo為Context的name
ContextUtil.enter("entranceTwo", "appA");
// Entry就是一個資源操作物件
Entry resource3 = null;
try {
// 獲取資源resource2的entry
resource2 = SphU.entry("resource2");
// 代碼能走到這里,說明當前對資源resource2的請求通過了流控
// 對資源resource2的相關業務處理,,,
// 獲取資源resource3的entry
resource3 = SphU.entry("resource3");
// 代碼能走到這里,說明當前對資源resource3的請求通過了流控
// 對資源resource3的相關業務處理,,,
} catch (BlockException e) {
// 代碼能走到這里,說明請求被限流,
// 這里執行降級處理
} finally {
if (resource2 != null) {
resource2.exit();
}
if (resource3 != null) {
resource3.exit();
}
}
// 釋放Context
ContextUtil.exit();
6 Node間的
Node:用于完成資料統計的介面
StatisticNode:統計節點,是Node介面的實作類,用于完成資料統計
EntranceNode:入口節點,一個Context會有一個入口節點,用于統計當前
Context的總體流量資料
DefaultNode:默認節點,用于統計一個資源在當前Context中的流量資料
ClusterNode:集群節點,用于統計一個資源在所有Context中的總體流量
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/301191.html
標籤:架構設計
