文章目錄
- 一、線程隔離
- 二、滑動窗口算法
- 三、令牌桶算法
- 四、漏桶算法
一、線程隔離
線程隔離有兩種方式實現:
- 線程池隔離:給每個服務調用業務分配一個線程池,利用線程池本身實現隔離效果
- 信號量隔離:不創建線程池,而是計數器模式,記錄業務使用的線程數量,達到信號量上限時,禁止新的請求。
Sentinel的線程隔離就是基于信號量隔離實現的。
二、滑動窗口算法
在熔斷功能中,需要統計異常請求或慢請求比例,也就是計數。在限流的時候,要統計每秒鐘的QPS,同樣是計數。
設置一個窗口的大小,然后窗口是勻速往前滑動的,在一段時間范圍內,請求落在同一個窗口的數量大于窗口閾值,就拒絕該請求。
sentinel中采用的計數器算法就是滑動窗口計數算法。
三、令牌桶算法
如圖:
說明:
- 以固定的速率生成令牌,存入令牌桶中,如果令牌桶滿了以后,多余令牌丟棄。
- 請求進入后,必須先嘗試從桶中獲取令牌,獲取到令牌后才可以被處理。
- 如果令牌桶中沒有令牌,則請求等待或丟棄。
基于令牌桶算法,每秒產生的令牌數量基本就是QPS上限。
當然也有例外情況,例如:
- 某一秒令牌桶中產生了很多令牌,達到令牌桶上限N,緩存在令牌桶中,但是這一秒沒有請求進入。
- 下一秒的前半秒涌入了超過2N個請求,之前緩存的令牌桶的令牌耗盡,同時這一秒又生成了N個令牌,于是總共放行了2N個請求。超出了我們設定的QPS閾值。
因此,在使用令牌桶算法時,盡量不要將令牌上限設定到服務能承受的QPS上限。而是預留一定的波動空間,這樣我們才能應對突發流量。
Sentinel中的熱點參數限流正是基于令牌桶算法實現的。
四、漏桶算法
漏桶算法與令牌桶相似,但在設計上更適合應對并發波動較大的場景。
簡單來說就是請求到達后不是直接處理,而是先放入一個隊列。而后以固定的速率從隊列中取出并處理請求。之所以叫漏桶算法,就是把請求看做水,隊列看做是一個漏了的桶。
如圖:
說明:
- 將每個請求視作"水滴"放入"漏桶"進行存儲;
- "漏桶"以固定速率向外"漏"出請求來執行,如果"漏桶"空了則停止"漏水”;
- 如果"漏桶"滿了則多余的"水滴"會被直接丟棄。
漏桶的優勢就是流量整型,不管并發量如何波動,經過漏桶處理后的請求一定是相對平滑的曲線。
sentinel限流中的排隊等待功能正是基于漏桶算法實現的。