三分鐘快速了解微服務中的限流邏輯與算法

在微服務架構(gòu)中一個會被經(jīng)常提及的概念就是“服務的熔斷與限流”。而之所以如此頻繁的提及這個概念邑闺,是因為在高并發(fā)場景下檩赢,瞬間的流量洪峰很容易超出微服務中各個系統(tǒng)的最大承受能力结序,從而造成服務的整體不可用沼本。

所以在設計高并發(fā)場景下的微服務架構(gòu)時噩峦,要根據(jù)服務所能承受的最大流量制定限流策略,從而保證在高并發(fā)場景下服務的穩(wěn)定性抽兆。今天的文章就和大家聊一聊關(guān)于限流的內(nèi)容识补,包括常見的限流算法及目前微服務架構(gòu)中主要的限流框架。

限流的概念

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

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

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

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

限流的必要性甚牲?

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

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

直到某一天圈浇,老板突然搞了一波促銷寥掐,系統(tǒng)的整體QPS達到了8000。此時每個節(jié)點的平均承載QPS為1600磷蜀,節(jié)點A率先扛不住直接掛了召耘,此時集群中還剩下4個節(jié)點,每個節(jié)點的平均承載QPS將達到2000褐隆,于是污它,剩下的4個節(jié)點也一臺接一臺掛了,整個服務就此雪崩庶弃。

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

系統(tǒng)整體QPS達到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ù)器減一柄错。每次請求進來的時候,先看一眼計數(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ù)器限流無法應對突發(fā)的流量增長。例如我們允許的閥值是1W蹲诀,此時計數(shù)器的值是0斑粱,那么當1W個請求瞬間全部打進來的時候,很可能服務就頂不住了脯爪。這是因為流量的緩緩增加和一下子涌入则北,對系統(tǒng)所產(chǎn)生的壓力是不一樣的。

況且一般限流都是限制在指定時間間隔內(nèi)的訪問量痕慢,而不是全時段服務的總體處理能力尚揣,所以計數(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)來說是不可承受的偶妖。如下圖所示:

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

<滑動窗口限流>

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

以時間窗口為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ù)進入漏桶中培慌,底部則定速處理請求豁陆,如果流量進入的速率高于底部請求被處理的速率,且當桶中的流量超過桶的大小時吵护,流量就會被溢出盒音。具體如下圖所示:

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

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

<令牌桶限流>

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

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

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

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

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

限流算法總結(jié)

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

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

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

微服務限流組件

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

其中Google Guava提供的限流工具類“RateLimiter”丧肴,是基于令牌桶實現(xiàn)的,并且擴展了算法胧后,支持了預熱功能芋浮。而阿里的Sentinel中的勻速限流策略,就是采用了漏桶算法壳快。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纸巷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子眶痰,更是在濱河造成了極大的恐慌瘤旨,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竖伯,死亡現(xiàn)場離奇詭異存哲,居然都是意外死亡,警方通過查閱死者的電腦和手機七婴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進店門宏胯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人本姥,你說我怎么就攤上這事肩袍。” “怎么了婚惫?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵氛赐,是天一觀的道長魂爪。 經(jīng)常有香客問我,道長艰管,這世上最難降的妖魔是什么滓侍? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮牲芋,結(jié)果婚禮上撩笆,老公的妹妹穿的比我還像新娘。我一直安慰自己缸浦,他們只是感情好夕冲,可當我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著裂逐,像睡著了一般歹鱼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卜高,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天弥姻,我揣著相機與錄音,去河邊找鬼掺涛。 笑死庭敦,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的薪缆。 我是一名探鬼主播螺捐,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矮燎!你這毒婦竟也來了定血?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤诞外,失蹤者是張志新(化名)和其女友劉穎澜沟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體峡谊,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡茫虽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了既们。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片濒析。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖啥纸,靈堂內(nèi)的尸體忽然破棺而出号杏,到底是詐尸還是另有隱情,我是刑警寧澤斯棒,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布盾致,位于F島的核電站主经,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏庭惜。R本人自食惡果不足惜罩驻,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望护赊。 院中可真熱鬧惠遏,春花似錦、人聲如沸骏啰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽器一。三九已至课锌,卻和暖如春厨内,著一層夾襖步出監(jiān)牢的瞬間祈秕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工雏胃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留请毛,地道東北人。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓瞭亮,卻偏偏與公主長得像方仿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子统翩,可洞房花燭夜當晚...
    茶點故事閱讀 45,982評論 2 361