最近寫了一個限流的插件,因此避免不了的接觸到了一些限流算法。本篇文章就來分析一下這幾種常見的限流算法nginx
這個算法能夠說是限流算法中最簡單的一種算法了。git
核心思想github
計數器算法的意思呢就是當接口在一個時間單位中被訪問時,我就記下來訪問次數,直到它訪問的次數到達上限。redis
涉及變量算法
條件一框架
當一個請求過來時,咱們就會獲得這個key。分佈式
1 2 3 4 5 6 7 8 9 |
if(存在key){ value++; if(value>=limit){ 不能訪問 } }else{ 添加key,value爲1 設置key過時時間爲expire } |
條件二lua
既然條件一已經實現了,那條件二會複雜麼 ?spa
相比於條件一來講就是同一個key對應了多個用戶。那麼咱們只須要把key加上用戶的信息就能夠了。好比說 key_用戶一、key_用戶2。插件
核心思想
漏桶算法的意思呢就是一個接口在一個時間單位中容許被訪問次數是動態變化的(假如一分鐘容許訪問60次,那麼從開始計時時無論有沒有被訪問第59秒只容許訪問59次,30秒只容許30次)。爲何這樣呢,由於有另一個線程在進行遞減操做
涉及變量
條件一
線程一:
1 2 3 4 5 6 7 8 |
if(存在key){ value--; if(value<=0){ 不能訪問 } }else{ 添加key,設置value爲limit } |
線程二:
1 2 3 |
while(過去interval時間){ 全部key的value-step } |
條件二
參考計數器算法條件二實現。
算法升級
能夠看到實現漏桶算法的話須要每隔interval時間都要另一條線程去遍歷所key的value去作遞減操做,那麼有沒有什麼辦法能夠省略這一步呢。答案是確定有。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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 2 3 4 5 6 7 8 |
if(存在key){ value++; if(value>=limit){ 不能訪問 } }else{ 添加key,設置value爲limit } |
線程二:
1 2 3 |
while(過去interval時間){ 全部key的value+step } |
條件二
參考計算器算法條件二實現。
算法升級
參考漏桶算法升級實現。
代碼實現請參考個人限流框架https://github.com/2388386839/syj-ratelimit
本文出自http://zhixiang.org.cn,轉載請保留。