限流是在微服務介面時,面對高併發場景必須考慮的問題。現在限流演算法主要有以下幾種:
其中令牌桶演算法變種還可以分為
單速率三色標記演算法
雙速率三色標記演算法
計數器法是限流演算法裡最簡單也是最容易實現的一種演算法。一般是限制一段時間能夠通過的請求數,比如某個介面規定5秒鐘的訪問次數不能超過10次,那麼我們我們可以設定乙個計數器counter,其有效時間為5秒鐘(即每5秒鐘計數器就會被重置為0),每當乙個請求過來的時候,counter就+1,如果counter的值大於等於10,就直接返回。
**實現
/**
* 限制為5秒10次
*/private long rangeseconds = 5l;
private integer maxrate = 10;
/*** 優點:編碼簡單
* 缺點:邊界值統計不準確
*/public object setnxlimit(long userid)
return increment;
}
**雖然簡單但是有個十分致命的問題,就是臨界問題,如果每秒持續傳送請求,會造成一直提示限流的情況,原因是因為計數器演算法限流對於最後一次請求時會一直對key進行續期導致的。
滑動視窗,又稱rolling window。為了解決計數器法統計精度太低的問題,引入了滑動視窗演算法。滑動視窗的主要原理比較簡單,將時間單位進行拆分,比如5秒的統計範圍,會將它劃分成5個1秒鐘。當請求進來的時候,會判斷當前請求屬於哪個時間片,然後將對應的時間片的統計值+1,再判斷當前值加上前4個時間片的總值是否超過設定的閾值。當時間已經到達第6個時間片時,會先刪除第乙個時間片。統計值會隨著時間片的滾動不停的按照時間片進行統計。
具體要將單位時間拆分為多少片,要根據實際情況來決定。當然,毫無疑問的是切分的越小,毛刺現象也越少。系統統計也越準確,隨之就是記憶體占用會越大,因為你的這個視窗的陣列會更大。
**實現思路就是定義好分片數量,每個分片都有乙個獨立的計數器,所有的分片合計為乙個陣列。當請求來時,按照分片規則,判斷請求應該劃分到哪個分片中去。要判斷是否超過閾值,就將前n個統計值相加,對比定義的閾值即可。
/**
* 滑動視窗
* 優點:統計精準,可以解決邊界值
* 缺點:如果限制範圍長,則資料量可能會比較大
*/public object windowlimit(long userid)
return count;
}
雖然解決了邊界問題,但是隨著使用者量增加記憶體的占用會隨之增加。
令牌桶演算法,又稱token bucket。和 leaky bucket 效果一樣但方向相反的演算法,更加容易理解.隨著時間流逝,系統會按恆定1/qps時間間隔(如果qps=100,則間隔是10ms)往桶裡加入token(想象和漏洞漏水相反,有個水龍頭在不斷的加水),如果桶已經滿了,令牌就溢位了。如果桶未滿,令牌可以積累。新請求來臨時,會各自拿走乙個token,如果沒有token可拿了就阻塞或者拒絕服務.
/**
* 令牌桶
* 優點:
*/public object tokenbucketlimit(long userid) else else
}return null;
}
漏斗(leaky bucket)演算法思路很簡單,水(請求)先進入到漏桶裡,漏桶以一定的速度出水(介面有響應速率),當水流入速度過大會直接溢位(訪問頻率超過介面響應速率),然後就拒絕請求,而當入小於出的情況下,漏桶不起任何作用。可以看出漏桶演算法能強行限制資料的傳輸速率。
/**
* 漏斗演算法限流
*/public object funnellimit(long userid) else else
}}
參考文章
大話常用限流演算法與應用場景
常見限流演算法介紹
高併發之限流演算法
自定義註解實現介面限流
大話常用限流演算法與應用場景
公司產品老大讓做乙個搶金幣的活動,規定乙個使用者5秒內最多搶10個金幣 初級工程師小j junior 同學拿到這個需求後立馬就開幹,直接用userid為key在redis中儲存,來乙個請求就讓計數器自增一下再拿到自增後的結果,判斷結果值是否超過了規定的閥值,再來個將key設為5秒過期 小a然後快速寫...
Hash演算法應用場景
一.雜湊演算法的定義 1.雜湊演算法又叫雜湊演算法,是將任意長度的二進位制值對映為較短的固定長度的二進位制值,這個小的二進位制值稱為雜湊值。它的原理其實很簡單,就是把一段交易資訊轉換成乙個固定長度的字串。2.雜湊表是基於快速訪問的角度設計的,是一種典型的空間換時間的做法,二.從set map談到ha...
演算法 常用經典動態規劃應用場景總結
1 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有數字累加起來就是路徑和,返回所有路徑中最小路徑和,如果給定的m如大家看到的樣子,路徑1,3,1,0,6,1,0就是路徑中和最小的,所以返回12。矩陣m13 5981 3450 6188 40解題思路 生成大小和m...