LeapArray
字段
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iM1MTM0ATMlhjMxQGMxEmYlVWZ0kjZ5QWM3EWYhVWYk9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
條件(謂詞)更新鎖,僅在不使用目前桶時使用。
内部核心數組 array,它的長度為 60,就是有 60 個視窗,每個視窗長度為 1 秒,一分鐘走完一輪。
然後下一輪開啟“覆寫”操作。
每個視窗是一個 WindowWrap 類執行個體。
添加資料的時候,先判斷目前走到哪個視窗了(目前時間(s) % 60 即可),然後需要判斷這個視窗是否是過期資料,如果是過期資料(視窗代表的時間距離目前已經超過 1 分鐘),需要先重置這個視窗執行個體的資料。
統計資料同理,如統計過去一分鐘的 QPS 資料,就是将每個視窗的值相加,當中需要判斷視窗資料是否是過期資料,即判斷視窗的 WindowWrap 執行個體是否是一分鐘内的資料。
核心邏輯都封裝在了 currentWindow(long timeMillis) 和 values(long timeMillis)方法中。
添加資料的時候,我們要先擷取操作的目标視窗,也就是
分次元資料統計
currentWindow
Sentinel 在這裡處理初始化和過期重置的情況
擷取資料,使用的是
values
- 傳回“有效”視窗中的資料
-
阿裡 Sentinel 源碼解析(中)LeapArray分次元資料統計案例 - isWindowDeprecated
-
阿裡 Sentinel 源碼解析(中)LeapArray分次元資料統計案例
案例
紅色部分的Context 代表一個調用鍊的入口,Context 執行個體設定在 ThreadLocal,是以它是跟着線程走的,如果要切換線程,需要手動切換。
ContextUtil#enter 有倆參數:
-
context name
調用鍊的入口,以區分不同調用鍊路,預設是
-
阿裡 Sentinel 源碼解析(中)LeapArray分次元資料統計案例 - origin
調用方辨別,作用
黑白名單的授權控制
統計諸如從應用 application-a 發起的對目前應用 interfaceXxx() 接口的調用,目前這個資料會被統計,但是 dashboard 中并不展示
進入 BlockException 異常分支,代表該次請求被流量控制規則限制,一般會讓代碼走入到熔斷降級邏輯。當然,BlockException 其實有好多個子類
亦可 catch 具體子類處理。
SphU#entry 方法的參數:
第一個參數
辨別資源,通常就是我們的接口辨別,對于資料統計、規則控制等,我們一般都是在這個粒度上進行的,根據這個字元串來唯一辨別,它會被包裝成 ResourceWrapper 執行個體。
第二個參數
辨別資源的類型
-
EntryType.IN
入口流量,比如我們的接口對外提供服務,那通常就是控制入口流量
- EntryType.OUT
-
阿裡 Sentinel 源碼解析(中)LeapArray分次元資料統計案例 - 預設就是出口流量,它的業務需要調用訂單服務,像這種情況,壓力其實都在訂單服務,那就指定它為出口流量。
流量類型在 SystemSlot 類中用以實作自适應限流,根據系統健康狀态來判斷是否要限流,如果是 OUT 類型,由于壓力在外部系統中,是以就不需要執行該規則。
若在一個方法中寫,要注意内層的 Entry 先 exit,才能做外層的 exit,否則會抛出異常。源碼角度來看,是在 Context 執行個體中,儲存了目前的 Entry 執行個體。