溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何理解微服務(wù)中的限流邏輯與算法

發(fā)布時間:2021-10-28 15:50:23 來源:億速云 閱讀:179 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“如何理解微服務(wù)中的限流邏輯與算法”,在日常操作中,相信很多人在如何理解微服務(wù)中的限流邏輯與算法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何理解微服務(wù)中的限流邏輯與算法”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

限流的概念

先介紹下什么是限流?其實日常生活中的限流場景隨處可見,例如北京地鐵早高峰,每天都是人山人海,如果大家一起蜂擁進(jìn)站,將很容易造成站內(nèi)擁堵,所以地鐵站一般都會進(jìn)站口設(shè)置像迷宮一樣的柵欄,大家轉(zhuǎn)圈圈分批進(jìn)站,這就是一種典型的限流場景。

那么在微服務(wù)中的限流具體是指什么呢?從字面上看,限流限的是流量,在不同場景下流量的定義是不同的,可以是QPS(每秒請求數(shù))、TPS(每秒事務(wù)處理數(shù)),也可以指純粹的網(wǎng)絡(luò)流量(如網(wǎng)卡通過的字節(jié)數(shù))等。

但我們通常所說的限流,是指限制達(dá)到系統(tǒng)的并發(fā)請求數(shù),使得系統(tǒng)能夠在自身能力允許的情況下正常處理部分用戶的請求,而對超出自身處理能力的用戶請求則予以拒絕,從而保證系統(tǒng)的穩(wěn)定運行。

限流不可避免的會造成用戶請求失敗或變慢的情況,從而在一定程度上影響用戶體驗,所以限流策略的制定需要以系統(tǒng)壓測的結(jié)果為參考,并在用戶體驗與系統(tǒng)穩(wěn)定性之間進(jìn)行平衡取舍。

限流的必要性?

前面我們提到限流的主要目的是為了保證系統(tǒng)的穩(wěn)定性。在日常的業(yè)務(wù)中,如果遇到像雙十一之類的促銷活動,或者遇到爬蟲等不正常的流量等情況,用戶流量突增,但后端服務(wù)的處理能力是有限的,如果不能有效處理突發(fā)流量,那么后端服務(wù)就很容易被打垮。

可以設(shè)想這樣一個場景:"某服務(wù)單節(jié)點可以承受的QPS是1000,該服務(wù)共有5個節(jié)點,日常情況下服務(wù)的QPS為3000"。那么正常情況下該服務(wù)毫無壓力,根據(jù)負(fù)載均衡配置3000/5=600,每個節(jié)點的日常QPS才600左右。

直到某一天,老板突然搞了一波促銷,系統(tǒng)的整體QPS達(dá)到了8000。此時每個節(jié)點的平均承載QPS為1600,節(jié)點A率先扛不住直接掛了,此時集群中還剩下4個節(jié)點,每個節(jié)點的平均承載QPS將達(dá)到2000,于是,剩下的4個節(jié)點也一臺接一臺掛了,整個服務(wù)就此雪崩。

而如果我們的系統(tǒng)有限流機制,那么情況將會如何發(fā)展呢?

系統(tǒng)整體QPS達(dá)到8000,但由于集群整體限流了5000,所以超出集群承受力的那3000個請求將被拒絕,系統(tǒng)則會正常處理5000個用戶請求,這是對集群整體限流的情況。而對于各個節(jié)點來說,由于我的承受力只是1000QPS,那么超出1000的部分也將被拒絕。這樣雖然損失了部分用戶請求,但保證了整個系統(tǒng)的穩(wěn)定性,也給開發(fā)運維留下了系統(tǒng)擴容時間。

由此可見,限流對于系統(tǒng)的自我保護是非常重要的存在。那么限流具體怎么做呢?接下來我們總結(jié)下常見的限流算法。

常見的限流算法

常見的限流算法主要有:計數(shù)器、固定窗口,滑動窗口、漏桶、令牌桶。接下來我們分別介紹下這幾種限流算法。

<計數(shù)器限流>

計數(shù)器限流是最簡單粗暴的一種限流算法,例如系統(tǒng)能同時處理100個請求,那么可以在保存一個計數(shù)器,處理一個請求,計數(shù)器加一,一個請求處理完畢后計數(shù)器減一。每次請求進(jìn)來的時候,先看一眼計數(shù)器的值,如果超過閥值則直接拒絕。

在具體實現(xiàn)時,如果該計數(shù)器是存在單機內(nèi)存中,那么就實現(xiàn)了單機限流;而如果存在例如Redis中,集群中的所有節(jié)點依次為限流依據(jù),那么就算實現(xiàn)了集群限流算法。

優(yōu)點:實現(xiàn)簡單,單機例如諸如Java的Atomic等原子類就能實現(xiàn),集群則通過Redis的incr操作就能快速實現(xiàn)。

缺點:計數(shù)器限流無法應(yīng)對突發(fā)的流量增長。例如我們允許的閥值是1W,此時計數(shù)器的值是0,那么當(dāng)1W個請求瞬間全部打進(jìn)來的時候,很可能服務(wù)就頂不住了。這是因為流量的緩緩增加和一下子涌入,對系統(tǒng)所產(chǎn)生的壓力是不一樣的。

況且一般限流都是限制在指定時間間隔內(nèi)的訪問量,而不是全時段服務(wù)的總體處理能力,所以計數(shù)器限流不太適合高并發(fā)場景下的限流實現(xiàn)。

<固定窗口限流>

相對于計數(shù)器來說,固定窗口限流是以一段時間窗口內(nèi)的訪問量作為限流的依據(jù),計數(shù)器每過一個時間窗口就自動重置。其規(guī)則如下:

  • 請求次數(shù)小于閥值,允許訪問,計數(shù)器加1;

  • 請求次數(shù)大于閥值,拒絕訪問;

  • 本時間窗口過了之后,計數(shù)器自動清零;

固定窗口限流雖然看起來挺完美,但是它有固定窗口臨界的問題。例如系統(tǒng)每秒允許1000個請求,假如第一個時間窗口的間隔是0~1秒,但在第0.55秒處一下子涌入了1000個請求,過了1秒后計數(shù)清零,此時在1.05秒的時候又一下子涌入了1000個請求。

此時雖然在固定時間窗口內(nèi)的計數(shù)沒有超過閥值,但在全局看來0.55秒~1.05秒這0.5秒內(nèi)一下子卻涌入了2000個請求,而這對于閥值為1000/s的系統(tǒng)來說是不可承受的。如下圖所示:

如何理解微服務(wù)中的限流邏輯與算法

而為了解決這個問題,衍生出了滑動窗口限流的算法!

<滑動窗口限流>

滑動窗口限流解決了固定窗口臨界值的問題,可以保證任意時間窗口內(nèi)都不會超過限流閥值。相對于固定窗口,滑動窗口除了需要引入計數(shù)器外,還需要額外記錄時間窗口內(nèi)每個請求到達(dá)的時間點。

以時間窗口為1秒為例,規(guī)則如下:

  • 記錄每次請求的時間;

  • 統(tǒng)計每次請求的時間向前推1秒這個時間窗口內(nèi)的請求數(shù),且1秒前的數(shù)據(jù)可以刪除;

  • 統(tǒng)計的請求數(shù)小于閥值則記錄該請求的時間,并允許通過,反之則拒絕該請求;

雖然看起來很OK,但是滑動窗口也無法解決短時間之內(nèi)集中流量的沖擊。例如每秒限制1000個請求,但是有可能存在前5毫秒的時候,閥值就被打滿的情況,理想情況下每10毫秒來100個請求,那么系統(tǒng)對流量的處理就會更加平滑。

但在真實場景中是很難控制請求的頻率的。所以為了解決時間窗口類算法的痛點,又出現(xiàn)了漏桶算法。

<漏桶限流>

漏桶算法的基本思想是,流量持續(xù)進(jìn)入漏桶中,底部則定速處理請求,如果流量進(jìn)入的速率高于底部請求被處理的速率,且當(dāng)桶中的流量超過桶的大小時,流量就會被溢出。具體如下圖所示:

如何理解微服務(wù)中的限流邏輯與算法

漏桶算法的特點是寬進(jìn)嚴(yán)出,無論請求的速率有多大,底部的處理速度都勻速進(jìn)行。這種算法的特點有點類似于消息隊列的處理機制,一般來說漏桶算法也是由隊列來實現(xiàn)的。

但漏桶算法的這種特點,實際上即是它的優(yōu)點也是缺點。有時候面對突發(fā)流量,我們往往會希望在保持系統(tǒng)穩(wěn)定的同時,能更快地處理用戶請求以提升用戶體驗,而不是按部就班的佛系工作。在這種情況下又出現(xiàn)了令牌桶這樣的限流算法,它在應(yīng)對突發(fā)流量時,可以比漏桶算法更加激進(jìn)。

<令牌桶限流>

令牌桶與漏桶的原理類似,只是漏桶是底部勻速處理,而令牌桶則是定速的向桶里塞入令牌,然后請求只有拿到了令牌才會被服務(wù)器處理。具體規(guī)則如下:

  • 定速的向桶中放入令牌;

  • 令牌數(shù)量超過桶的限制,則丟棄;

  • 請求來了先向桶中索取令牌,索取成功則通過被處理,否則拒絕;

如何理解微服務(wù)中的限流邏輯與算法

可以看出令牌桶在應(yīng)對突發(fā)流量時,不會想漏桶那樣勻速的處理,而是在短時間內(nèi)請求可以同時取走桶中的令牌,并及時的被服務(wù)器處理。所以在應(yīng)對突發(fā)流量的場景下,令牌桶表現(xiàn)更強。

限流算法總結(jié)

經(jīng)過上述的描述,好像漏桶、令牌桶比時間窗口類算法好多了,那么時間窗口類算法是不是就沒啥用了呢?

其實并不是,雖然漏桶、令牌桶對比時間窗口類算法對流量的整形效果更好,但是它們也有各自的缺點,例如令牌桶,假如系統(tǒng)上線時沒有預(yù)熱,那么可能會出現(xiàn)由于此時桶中還沒有令牌,而導(dǎo)致請求被誤殺的情況;而漏桶中由于請求是暫存在桶中的,所以請求什么時候能被處理,則是有延時的,這并不符合互聯(lián)網(wǎng)業(yè)務(wù)低延時的要求。

所以令牌桶、漏桶算法更適合阻塞式限流的場景,即后臺任務(wù)類的限流。而基于時間窗口的限流則更適合互聯(lián)網(wǎng)實施業(yè)務(wù)限流的場景,即能處理快速處理,不能處理及時響應(yīng)調(diào)用方,避免請求出現(xiàn)過長的等待時間。

微服務(wù)限流組件

如果你有興趣實際上也是可以自己實現(xiàn)一個限流組件的,只不過這種輪子已經(jīng)早有人造好了。目前市面上比較流行的限流組件主要有:Google  Guava提供的限流工具類“RateLimiter”、阿里開源的Sentinel。

其中Google  Guava提供的限流工具類“RateLimiter”,是基于令牌桶實現(xiàn)的,并且擴展了算法,支持了預(yù)熱功能。

到此,關(guān)于“如何理解微服務(wù)中的限流邏輯與算法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI