Sentinel -- FLOW SLOT核心原理篇

這個節點是sentinel流控接口,主要承擔的做用是限流和預熱。仍是老套路,在介紹源碼以前先介紹一下源碼中用到的幾個核心原理,這樣你們看源碼相對輕鬆一些。算法

一、核心算法

1.1 漏洞算法和令牌通算法

漏桶能夠看做是一個帶有常量服務時間的單服務器隊列,若是漏桶(包緩存)溢出,那麼數據包會被丟棄。 在網絡中,漏桶算法能夠控制端口的流量輸出速率,平滑網絡上的突發流量,實現流量整形,從而爲網絡提供一個穩定的流量。api

如圖所示,把請求比做是水,水來了都先放進桶裏,並以限定的速度出水,當水來得過猛而出水不夠快時就會致使水直接溢出,即拒絕服務。緩存

1.2令牌桶算法

令牌桶算法的原理是系統會以一個恆定的速度往桶裏放入令牌,而若是請求須要被處理,則須要先從桶裏獲取一個令牌,當桶裏沒有令牌可取時,則拒絕服務。從原理上看,令牌桶算法和漏桶算法是相反的,一個「進水」,一個是「漏水」。

1.3預熱桶算法

系統在初始化或者長時間處於低利用率下,系統因爲所依賴資源的限制,並不能立馬達到它正常的服務水平;例如系統依賴的緩存過時致使新的請求會直接請求 db,再好比不少系統使用了鏈接池,長時間的 idle 狀況下鏈接池只會保持少許的鏈接,新的請求會從新建立鏈接,這些都是耗時操做,完成這些操做以後,系統才能到達正常的服務水平。這時候變須要預熱桶算法。
 
預熱桶算法本質是按照一個 y=mx+b的一個線性函數,將投入令牌桶的時間間隔又大到小的過程。下面是guava源碼中的一個函數圖。
throttling
|
cold + | /
interval | | /.
| | / .
| |/ .
| + . ← "f(storedPermits)"
| /| .
| / | .
| / | .
stable +----------/ | . ← "warmup period"
interval | . | . is the area of the trapezoid between thresholdPermits and maxPermits
| . | .
| . | .
0 +----------+---|---+--------------→ storedPermits
0 thresholdPermits maxPermits

咱們能夠定義一個冷卻因子(coldFactor) ,令系統處於最冷的狀態下獲取一個令牌的時長 coldInterval = stableInterval * coldFactor ;「預熱桶」從最冷狀態到完成預熱進入穩按期有個轉折點,到達這個轉折點時的令牌數量咱們用 thresholdPermits 表示;這樣,咱們就得到了一個獲取(一個)令牌的時長隨着令牌數量變化的連續函數 f(storedPermits) : 服務器

        1)  0 <= storedPermits <= thresholdPermits 時;f(storedPermits) = stableInterval; // 常數函數,函數值始終爲 stableInterval ;       網絡

       2) thresholdPermits <= storedPermits <= maxPermits 時,f(storedPermits) = (coldInterval - stableInterval) * storedPermits / (maxPermits -thresholdPermits); // 正比例函數,比例常數爲 (coldInterval - stableInterval) / (maxPermits - thresholdPermits) ;函數

在上面這張圖中,咱們畫一條與 x 軸垂直的線 n,這條線與函數曲線的交點的縱座標當前 storedPermits 數量下獲取單個令牌所需的時間;3d

當咱們從右向左移動 n 時,表示系統接收到請求,令牌正在被消耗,假設系統連續接收到 k 個請求,獲取對應令牌所須要的時間爲:t = f(maxPermits) + f(maxPermits - 1) + f(maxPermits - 2) + ... + f(maxPermits - k),經過微積分的知識能夠看出來這是在求函數 f 在 maxPermits - k 到 maxPermits 區間的定積分,能夠用這個區間的函數圖形的面積表示。也就是說圖中梯形的面積爲咱們的預熱時間。圖中矩形的面積爲預熱時間的一半。網上及guava源碼出的解釋:英文冷卻因子是3,而後code inteval 到 stable inteval的值是stable inteval到0值的2倍因此預熱面積也是2倍的關係。具體狀況以下圖:code

ps:我的理解這裏的解釋欠妥,以下圖若是①和②是二倍的關係還能夠理解。這是我的理解歡迎你們給出合理解釋。blog

二、FLOW SLOT源碼解讀

流控節點總體流程是:先驗證流量是否超過閥值,沒有的狀況下載進入下一個節點。token

代碼往下跟,最終進入單機限流模式下。
集羣限流在sentinel這個組件中我的不推薦,雖然集權能解決以下問題:
  • 假設集羣中有 10 臺機器,咱們給每臺機器設置單機限流閾值爲 10 qps,理想狀況下整個集羣的限流閾值就爲 100 qps。不過實際狀況下路由到每臺機器的流量可能會不均勻,會致使總量沒有到的狀況下某些機器就開始限流。
  • 每臺單機實例只關心本身的閾值,對於整個系統的全局閾值你們都不聞不問,當咱們但願爲某個 api 設置一個總的 qps 時(就跟爲 api 設置總的調用次數同樣),那這種單機模式的限流就沒法知足條件了。
可是,sentinel的集羣限流會引入新的服務新的依賴並無對其進行熔斷處理,原本是將來保護系統,若是用集羣限流會引入新的風險點。這是我的片面理解僅供參考。
 
接下來看下限流具體如何處理的
四個子類對應四種限流場景:快速失敗,預熱,排隊等待。

2.1直接限流快速失敗場景

當前請求數量加上滑動時間窗口統計的前一秒的請求數量大於設定閥值直接失敗。

2.2直接限流快速預熱場景

初始化場景就不說了相似前面的預熱桶的計算方式。最終計算一個函數,穩定的減小往桶裏方每一個token的時間,最終達到穩定PQS。
校驗是否經過
產生令牌
相關文章
相關標籤/搜索