一个基于用户的API限流策略 Rate Limit
1.?限流場(chǎng)景
在開(kāi)發(fā)高并發(fā)系統(tǒng)時(shí),有很多種方法可用來(lái)保護(hù)系統(tǒng):緩存、降級(jí)、限流等。
- 緩存:提升系統(tǒng)訪問(wèn)速度,增大系統(tǒng)處理能力
- 降級(jí):服務(wù)出現(xiàn)問(wèn)題或影響核心流程的性能時(shí),需要暫時(shí)屏蔽,待高峰過(guò)去或問(wèn)題解決后再打開(kāi)
- 限流:部分場(chǎng)景比如:稀缺資源(秒殺,搶購(gòu))、寫(xiě)服務(wù)(評(píng)論、下單)、頻繁復(fù)雜查詢(xún)(評(píng)論最后幾頁(yè))等,需要限制這些場(chǎng)景的并發(fā)/請(qǐng)求量
限流就是通過(guò)對(duì)并發(fā)訪問(wèn)/請(qǐng)求進(jìn)行限速或一個(gè)時(shí)間窗口內(nèi)的請(qǐng)求進(jìn)行限速,從而達(dá)到保護(hù)系統(tǒng)的目的。一般系統(tǒng)可以通過(guò)壓測(cè)來(lái)預(yù)估能處理的峰值,一旦達(dá)到設(shè)定的峰值閥值,則可以拒絕服務(wù)(定向錯(cuò)誤頁(yè)或告知資源沒(méi)有了)、排隊(duì)或等待(例如:秒殺、評(píng)論、下單)、降級(jí)(返回默認(rèn)數(shù)據(jù))
限流不能亂用,否則正常流量會(huì)出現(xiàn)一些奇怪的問(wèn)題,從而導(dǎo)致用戶(hù)抱怨。
2.?限流算法
常見(jiàn)限流算法:技術(shù)器、令牌桶和漏桶算法。
2.1.?計(jì)數(shù)器
計(jì)數(shù)器是最簡(jiǎn)單粗暴的算法。例如:一個(gè)服務(wù)每秒能處理100個(gè)請(qǐng)求。設(shè)置一個(gè)1s的滑動(dòng)窗口,窗口有10個(gè)格子,每個(gè)格子100ms,每100ms移動(dòng)一次,每次移動(dòng)都記錄當(dāng)前服務(wù)請(qǐng)求的次數(shù)。內(nèi)存中保存最近10次的次數(shù)(LinkedList)。格子每次移動(dòng)的時(shí)候判斷一次,最后一個(gè)格子和第一個(gè)格子的次數(shù)是否相差100,如果超過(guò),則進(jìn)行限流。
當(dāng)格子劃分的越多,那么滑動(dòng)窗口的滾動(dòng)越平滑,限流的統(tǒng)計(jì)就會(huì)越精確。
計(jì)數(shù)器的實(shí)現(xiàn)簡(jiǎn)單,但是是平均分配1秒鐘的請(qǐng)求,然而實(shí)際情況中的請(qǐng)求往往是動(dòng)態(tài)的,流量不平滑的。
?
2.2.?令牌桶
令牌桶算法是一個(gè)存放固定容量令牌(token)的桶,按照固定速率往桶里添加令牌。令牌桶的主要概念如下:
- 令牌按固定的速率被放入令牌桶中,例如:r tokens/秒
- 桶中最多存放b個(gè)令牌,當(dāng)桶滿(mǎn)時(shí),新添加的令牌被丟棄或拒絕
- 當(dāng)一個(gè)n字節(jié)大小的數(shù)據(jù)包到達(dá),將從桶中刪除n個(gè)令牌,接著數(shù)據(jù)包被發(fā)送到網(wǎng)絡(luò)上
- 如果桶中的令牌不足n個(gè),則不會(huì)刪除令牌,且數(shù)據(jù)包將被限流(丟棄或在緩沖區(qū)等待)
令牌桶根據(jù)放令牌的速率(r tokens/s)去控制輸出的速率(to network)
?
令牌桶的另外一個(gè)好處是可以方便的改變速度. 一旦需要提高速率,則按需提高放入桶中的令牌的速率. 一般會(huì)定時(shí)(比如100毫秒)往桶中增加一定數(shù)量的令牌, 有些變種算法則實(shí)時(shí)的計(jì)算應(yīng)該增加的令牌的數(shù)量.
2.3.?漏桶
漏桶(?Leaky Bucket?)算法思路很簡(jiǎn)單,水(請(qǐng)求)先進(jìn)入到漏桶里,漏桶以一定的速度出水(接口有響應(yīng)速率),當(dāng)水流入速度過(guò)大會(huì)直接溢出(訪問(wèn)頻率超過(guò)接口響應(yīng)速率),然后就拒絕請(qǐng)求,可以看出漏桶算法能強(qiáng)行限制數(shù)據(jù)的傳輸速率。
漏桶作為計(jì)量工具時(shí),可用于流量整形和流量控制,漏桶的主要概念如下:
- 一個(gè)固定容量的漏桶,按照常量固定速率流出水滴(流出請(qǐng)求)
- 如果桶是空的,則不需流出水滴
- 可以以任意速率流入水滴到漏桶(流入請(qǐng)求)
- 如果流入水滴超出了桶的容量,則流入的水滴溢出了(新流入的請(qǐng)求被拒絕),則漏桶容量是不變的
漏桶可以看做固定容量、固定流出速率的隊(duì)列,漏桶限制的是請(qǐng)求的流出速率,漏桶中裝的是請(qǐng)求
因?yàn)槁┩暗穆┏鏊俾适枪潭ǖ膮?shù),所以,即使網(wǎng)絡(luò)中不存在資源沖突(沒(méi)有發(fā)生擁塞),漏桶算法也不能使流突發(fā)(?burst?)到端口速率.因此,漏桶算法對(duì)于存在突發(fā)特性的流量來(lái)說(shuō)缺乏效率.
?
2.4.?令牌桶和漏桶的比較
| 請(qǐng)求何時(shí)拒絕 | 固定速率往桶中添加令牌,如果桶中令牌不夠,則拒絕新請(qǐng)求 | 流入請(qǐng)求速率任意,常量固定速率流出請(qǐng)求。當(dāng)流入請(qǐng)求數(shù)積累到漏桶容量時(shí),則拒絕新請(qǐng)求 |
| 速率限制 | 限制平均流入速率,允許一定程度的突發(fā)請(qǐng)求(支持一次拿多個(gè)令牌) | 限制常量流出速率(流出速率是固定值),從而平滑突發(fā)流入速率 |
?
參考:
基于Redis的限流系統(tǒng)的設(shè)計(jì)
?
總結(jié)
以上是生活随笔為你收集整理的一个基于用户的API限流策略 Rate Limit的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【spring5】spring5.x概览
- 下一篇: 37-SQLServer的审核/审计功能