最近寫了一個限流的插件,所以避免不了的接觸到了一些限流算法。本篇文章就來分析一下這幾種常見的限流算法
分析之前
依我個人的理解來說限流的話應該靈活到可以針對每一個接口來做。比如說一個類裏面有5個接口,那麼我的限流插件就應該能針對每一個接口就行不同的限流方案。所以呢,既然針對的每個接口所以就需要一個可以唯一標示這個接口的key(我取的是類名+方法名+入參)。
分佈式限流強烈推薦使用redis+lua或者nginx+lua來實現。
這裏用2個限流條件來做示例講一下常見的限流算法:
接口1它10秒鐘最大允許訪問100次
接口2它10秒鐘最大允許每個人訪問100次。
計數器算法
這個算法可以說是限流算法中最簡單的一種算法了。
核心思想
計數器算法的意思呢就是當接口在一個時間單位中被訪問時,我就記下來訪問次數,直到它訪問的次數到達上限。
涉及變量
接口(key)
時間單位(expire)
允許訪問多少次(limit)
訪問次數(value)
條件一
當一個請求過來時,我們就會得到這個key。
1 2 3 4 5 6 7 8 9 | if(存在key){ value++; if(value>=limit){ 不能訪問 } }else{ 添加key,value爲1 設置key過期時間爲expire } |
條件二
既然條件一已經實現了,那條件二會複雜麼 ?
相比於條件一來說就是同一個key對應了多個用戶。那麼我們只需要把key加上用戶的信息就可以了。比如說 key_用戶1、key_用戶2。
漏桶算法
核心思想
漏桶算法的意思呢就是一個接口在一個時間單位中允許被訪問次數是動態變化的(假如一分鐘允許訪問60次,那麼從開始計時時不管有沒有被訪問第59秒只允許訪問59次,30秒只允許30次)。爲什麼這樣呢,因爲有另外一個線程在進行遞減操作
涉及變量
接口(key)
時間單位(expire)
允許訪問多少次(limit)
遞減間隔時間(interval)
遞減步長(step)
剩餘可訪問次數(value)
key的訪問時間(lastUpdateTime)
當前時間(nowTime)(注意nowTime的取值應爲應用取得的時間而不是redis或者nginx取得的時間)