微服務(wù)容錯(cuò)與隔離:限流保護(hù),計(jì)數(shù)器+漏桶+令牌桶算法限流實(shí)現(xiàn)
限流保護(hù)
限流的目的是保護(hù)系統(tǒng)不被大量請(qǐng)求沖垮,通過(guò)限制請(qǐng)求的速度來(lái)保護(hù)系統(tǒng)。在電商的秒殺活動(dòng)中,限流是必不可少的一個(gè)環(huán)節(jié)。
計(jì)數(shù)器
比較簡(jiǎn)單的限流做法是維護(hù)一個(gè)單位時(shí)間內(nèi)的計(jì)數(shù)器,每次允許請(qǐng)求計(jì)數(shù)器都加1,當(dāng)單位時(shí)間內(nèi)計(jì)數(shù)器累加到設(shè)定的閾值后,之后的請(qǐng)求都被拒絕,直到超過(guò)單位時(shí)間,再將計(jì)數(shù)器重置為零。此方式有一個(gè)弊端:如果在單位時(shí)間1s內(nèi)允許100個(gè)請(qǐng)求,10ms已經(jīng)通過(guò)了100個(gè)請(qǐng)求,那后面的990ms只能拒絕請(qǐng)求,我們把這種現(xiàn)象稱為“突刺現(xiàn)象”。常用的更平滑的限流算法有兩種:漏桶算法和令牌桶算法。
漏桶算法
漏桶算法的思路很簡(jiǎn)單,水(請(qǐng)求)先進(jìn)入漏桶里,漏桶以一定的速度出水(接口有響應(yīng)速度),當(dāng)水流入的速度過(guò)大時(shí)(訪問(wèn)頻率超過(guò)接口響應(yīng)速度)會(huì)直接溢出,然后就拒絕請(qǐng)求。如下圖所示,可以看出漏桶算法能強(qiáng)行限制數(shù)據(jù)的傳輸速度。因?yàn)槁┩暗穆┏鏊俣仁枪潭ǖ?,所以,即使網(wǎng)絡(luò)中不存在資源沖突(沒(méi)有發(fā)生擁塞),漏桶算法也不能增大流量。因此,漏桶算法對(duì)于存在突發(fā)特性的流量來(lái)說(shuō)缺乏效率。

令牌桶算法
令牌桶算法和漏桶算法效果相似,令牌桶算法更加容易理解。隨著時(shí)間的流逝,系統(tǒng)會(huì)按恒定的1/QPS時(shí)間間隔(如果QPS=100,則間隔是10ms)往桶里加入令牌(就像有個(gè)水龍頭在不斷地加水),如果桶已經(jīng)滿了就不再加了。新請(qǐng)求來(lái)臨時(shí),會(huì)拿走一個(gè)令牌,如果沒(méi)有令牌可拿了,就阻塞或者拒絕請(qǐng)求,如下圖所示。

令牌桶算法的另外一個(gè)好處是可以方便地改變速度。一旦需要提高速度,則按需提高放入桶中的令牌的速度即可。一般會(huì)定時(shí)(比如100ms)往桶中增加一定數(shù)量的令牌,有些變種算法則實(shí)時(shí)地計(jì)算應(yīng)該增加的令牌的數(shù)量。
限流實(shí)現(xiàn)
Guava限流器RateLimiter是基于令牌桶算法實(shí)現(xiàn)的一個(gè)多線程限流器,它可以均勻地處理請(qǐng)求,當(dāng)然它并不是一個(gè)分布式限流器,只是對(duì)單機(jī)進(jìn)行限流。它可以定時(shí)拉取接口數(shù)據(jù),下面是一個(gè)簡(jiǎn)單的限流功能的實(shí)例。
首選引入Maven依賴:

然后使用Guava限流,Java代碼實(shí)現(xiàn)如下:


本文給大家講解的內(nèi)容是微服務(wù)容錯(cuò)與隔離:限流保護(hù),計(jì)數(shù)器+漏桶+令牌桶算法限流實(shí)現(xiàn)
下篇文章給大家講解的內(nèi)容是微服務(wù)容錯(cuò)與隔離:熔斷保護(hù)、超時(shí)與重試
覺(jué)得文章不錯(cuò)的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
感謝大家的支持!
