簡析限流算法
1.簡介
限流顧名思義是限制流量,限制流量的目的是為了保障服務(wù)穩(wěn)定運行,避免服務(wù)被流量沖垮。當流量超出服務(wù)處理能力時,部分請求將會被限流組件攔截。被攔截的請求可能會被丟棄,如果是 C 端請求,那么這個請求可能會被導(dǎo)向指定的錯誤頁上,而不是生硬的拒絕。這里我們丟棄掉一部分請求,以保證大部分請求可以正常響應(yīng)。如果我們不這樣做,那么服務(wù)崩潰后,所有請求都將無法響應(yīng)了。當一臺機器崩潰后,該機器的所有流量將由其他機器承擔(dān),這樣就會造成剩余機器壓力增大,進而導(dǎo)致奔潰,最后形成雪崩。除此之外,服務(wù)崩潰還會造成數(shù)據(jù)不一致的嚴重問題,特別是一些敏感數(shù)據(jù)。比如對于電商網(wǎng)站,如果后臺服務(wù)準備將某筆訂單數(shù)據(jù)存入數(shù)據(jù)庫時,服務(wù)突然崩潰,導(dǎo)致數(shù)據(jù)沒有落庫。這個時候,開發(fā)同學(xué)就要想辦法修訂數(shù)據(jù)了。
綜上,我們可以看出來限流的重要性。接下來,我將向大家介紹三種常用的限流算法,分別是計數(shù)器、漏桶算法和令牌桶算法。下面我們從最簡單的計數(shù)器開始說起。
2.限流算法
2.1 計數(shù)器
計數(shù)器算法的思想很簡單,每當一個請求到來時,我們就將計數(shù)器加一,當計數(shù)器數(shù)值超過閾值后,就拒絕余下請求。一秒鐘后,我們將計數(shù)器清零,開始新一輪的計數(shù)。計數(shù)器算法簡單粗暴,易于實現(xiàn)。但是缺點也是有的,也就是所謂的"突刺現(xiàn)象"。舉例說明一下,假如我們給計數(shù)器設(shè)置的閾值為100。系統(tǒng)瞬間內(nèi)(比如10毫秒內(nèi))有200個請求到來,這個時候計數(shù)器只能放過其中的100個請求,余下的100個請求全部被拒絕掉。如果第二秒內(nèi)沒有請求到來,那么系統(tǒng)就處于空閑狀態(tài)。也就是上一秒忙的要死,這一秒又閑的要死。如果我們能用一個容器將剩余的100個請求緩存起來,待計數(shù)器重置后再將這些請求放出來。這樣系統(tǒng)在這兩秒內(nèi)的吞吐量就由100變成了200,提升了一倍?;谶@個思考,下面我們再來看看漏桶算法。
2.2 漏桶算法
漏桶算法由流量容器、流量入口和出口組成。其中流量出口流速即為我們期望的限速值,比如 100 QPS。漏桶算法除了具備限流能力,還具備流量整型功能。下面我們通過一張圖來了解漏桶算法。

圖片來源:未知
如上圖,流入漏桶流量的流速是不恒定的,經(jīng)過漏桶限速后,流出流量的速度是恒定的。需要說明的是,漏桶的容量是有限的,一旦流入流量超出漏桶容量,這部分流量只能被丟棄了。
漏桶是一個比較好的限流整型工具,不過漏桶不能處理突發(fā)流量,一些觀點認為這是它的一個缺點。不過如果較起真來,我覺得這個缺點是不成立的。畢竟漏桶本就是用來平滑流量的,如果支持突發(fā),那么輸出流量反而不平滑了。如果要找一種能夠支持突發(fā)流量的限流算法,那么令牌桶算法可以滿足需求。
2.3 令牌桶算法
令牌桶和漏桶頗有幾分相似,只不過令牌通里存放的是令牌。它的運行過程是這樣的,一個令牌工廠按照設(shè)定值定期向令牌桶發(fā)放令牌。當令牌桶滿了后,多出的令牌會被丟棄掉。每當一個請求到來時,該請求對應(yīng)的線程會從令牌桶中取令牌。初期由于令牌桶中存放了很多個令牌,因此允許多個請求同時取令牌。當桶中沒有令牌后,無法獲取到令牌的請求可以丟棄,或者重試。下面我們來看一下的令牌桶示意圖:

圖片來源:未知
盡管令牌桶允許突發(fā)流量,但突發(fā)流量速率 R1 + 限流速率 R2 不能超過系統(tǒng)最大的處理能力 Rt,即 R1 + R2 ≤ Rt,否則會沖垮系統(tǒng)。
3.總結(jié)
以上就是本篇文章的全部內(nèi)容。本篇文章簡單分析幾種常見限流算法的運行過程,限于能力原因,文章若有錯誤不妥之處還請指明。除了文字性描述,這里也把三種算法的簡單實現(xiàn)代碼貼出來 RateLimiter,有興趣的同學(xué)自取。
好了,本篇文章到這里就結(jié)束了,感謝大家的閱讀。
本文在知識共享許可協(xié)議 4.0 下發(fā)布,轉(zhuǎn)載需在明顯位置處注明出處
作者:田小波
本文同步發(fā)布在我的個人博客:http://www.tianxiaobo.com

本作品采用知識共享署名-非商業(yè)性使用-禁止演繹 4.0 國際許可協(xié)議進行許可。

浙公網(wǎng)安備 33010602011771號