大型網站限流算法的實現和改造

最近寫了一個限流的插件,所以避免不了的接觸到了一些限流算法。本篇文章就來分析一下這幾種常見的限流算法

分析之前

依我個人的理解來說限流的話應該靈活到可以針對每一個接口來做。比如說一個類里面有5個接口,那么我的限流插件就應該能針對每一個接口就行不同的限流方案。所以呢,既然針對的每個接口所以就需要一個可以唯一標示這個接口的key(我取的是類名+方法名+入參)。

分布式限流強烈推薦使用redis+lua或者nginx+lua來實現。

這里用2個限流條件來做示例講一下常見的限流算法:

1. 接口1它10秒鐘最大允許訪問100次

2. 接口2它10秒鐘最大允許每個人訪問100次。

計數器算法

這個算法可以說是限流算法中最簡單的一種算法了。

核心思想

計數器算法的意思呢就是當接口在一個時間單位中被訪問時,我就記下來訪問次數,直到它訪問的次數到達上限。

涉及變量

1.接口(key)

2.時間單位(expire)

3.允許訪問多少次(limit)

4.訪問次數(value)

條件一

當一個請求過來時,我們就會得到這個key。


if(存在key){

? ???? value++;

????if(value>=limit){

? ???? 不能訪問

????? }

}else{

????添加key,value為1

????設置key過期時間為expire

? }

條件二

既然條件一已經實現了,那條件二會復雜么 ?

相比于條件一來說就是同一個key對應了多個用戶。那么我們只需要把key加上用戶的信息就可以了。比如說 key_用戶1、key_用戶2。

漏桶算法

核心思想

漏桶算法的意思呢就是一個接口在一個時間單位中允許被訪問次數是動態變化的(假如一分鐘允許訪問60次,那么從開始計時時不管有沒有被訪問第59秒只允許訪問59次,30秒只允許30次)。為什么這樣呢,因為有另外一個線程在進行遞減操作

涉及變量

1.接口(key)

2.時間單位(expire)

3.允許訪問多少次(limit)

4.遞減間隔時間(interval)

5.遞減步長(step)

6.剩余可訪問次數(value)

7.key的訪問時間(lastUpdateTime)

8.當前時間(nowTime)(注意nowTime的取值應為應用取得的時間而不是redis或者nginx取得的時間)

條件一

線程一:


if(存在key){

????value--;

????if(value<=0){

? ???????? 不能訪問

? ???? }

}else{

????添加key,設置value為limit

? }

線程二:


while(過去interval時間){

????所有key的value-step

? }

條件二

參考計數器算法條件二實現。

算法升級

可以看到實現漏桶算法的話需要每隔interval時間都要另外一條線程去遍歷所key的value去做遞減操作,那么有沒有什么辦法可以省略這一步呢。答案是肯定有。


if(存在key){

? ???? value--;

????if((nowTime-lastUpdateTime)>interval){

????????value=value-(nowTime-lastUpdateTime)/interval*step;

????????lastUpdateTime=nowTime;

????? }

????if(value<=0){

????? 不能訪問

????? }

}else{

? ???? 添加key,設置value為limit;

????lastUpdateTime=nowTime;

? }

令牌桶算法

核心思想

令牌桶算法呢,恰恰是和漏桶算法相反的一個算法,不過還是推薦你使用這個。這個算法的原理我不講,我覺得聰明的你看了偽代碼就明白了。

涉及變量

1.接口(key)

2.時間單位(expire)

3.允許訪問多少次(limit)

4.遞增間隔時間(interval)

5.遞增步長(step)

6.當前可訪問次數(value)

7.key的訪問時間(lastUpdateTime)

8.當前時間(nowTime)(參照漏桶算法需要注意的點)

條件一

線程一:


if(存在key){

? ???? value++;

????if(value>=limit){

????????? 不能訪問

????? }

}else{

????添加key,設置value為limit

? }

線程二:

while(過去interval時間){

????所有key的value+step

? }

條件二

參考計算器算法條件二實現。

算法升級

參考漏桶算法升級實現。

代碼

代碼實現請參考我的限流框架https://github.com/shiyujun/syj-ratelimit


本文出自http://zhixiang.org.cn,轉載請保留。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,076評論 2 375

推薦閱讀更多精彩內容