出處:https://segmentfault.com/a/1190000039069027
一、限流是高可用的利器之一眾所皆知,限流是透過對某段時間(如雙11)的大流量請求進行限速,以此達到保護系統的目的。大促之前,我們可以透過壓測等手段測出系統當前最大承受的處理閾值,即峰值QPS/TPS,一旦流量達到峰值,我們可以實施降級,比如讓使用者排隊等待,稍後再試。下面就來詳細聊聊限流的常用演算法和實施策略。
二、限流演算法常見的限流演算法有令牌桶,漏桶。計數器、訊號量也可以用來做簡單的限流。
1.令牌桶演算法令牌桶演算法的基本過程如下(摘自百度百科):
1.假如使用者配置的平均傳送速率為r,則每隔1/r秒一個令牌被加入到桶中;
2.假設桶最多可以存發b個令牌。如果令牌到達時令牌桶已經滿了,那麼這個令牌會被丟棄;
5.演算法允許最長b個位元組的突發,但從長期執行結果看,資料包的速率被限制成常量r。對於在流量限制外的資料包可以以不同的方式處理:
它們可以被丟棄;
它們可以排放在佇列中以便當令牌桶中累積了足夠多的令牌時再傳輸;
它們可以繼續傳送,但需要做特殊標記,網路過載的時候將這些特殊標記的包丟棄。
2.漏通演算法漏桶演算法的基本過程如下(摘自百度百科):
如果到達速率≤輸出速率,則漏桶不起作用。
如果到達速率>輸出速率,則需考慮漏桶是否能承擔這個瞬間的流量。
1) 若資料包到達的速率-漏桶流出的速率≤配置的漏桶突發速率,則資料包可被不延時的送出。
2) 若資料包到達的速率-漏桶流出的速率>配置的漏桶突發速率,則多餘的資料包被儲存到漏桶中。暫存在漏桶中的資料包在不超過漏桶容量的情況下延時發出。
3) 若資料包到達的速率-漏桶流出的速率>配置的漏桶突發速率,且資料包的數量已經超過漏桶的容量,則這些資料包將被丟棄。
3.令牌桶演算法和漏桶演算法的區別漏桶演算法與令牌桶演算法在表面看起來類似,很容易將兩者混淆。但事實上,這兩者具有截然不同的特性,且為不同的目的而使用。漏桶演算法與令牌桶演算法的區別在於:
1.漏桶演算法能夠強行限制資料的傳輸速率。
2.令牌桶演算法能夠在限制資料的平均傳輸速率的同時還允許某種程度的突發傳輸。
需要說明的是:在某些情況下,漏桶演算法不能夠有效地使用網路資源。因為漏桶的漏出速率是固定的,所以即使網路中沒有發生擁塞,漏桶演算法也不能使某一個單獨的資料流達到埠速率。因此,漏桶演算法對於存在突發特性的流量來說缺乏效率。而令牌桶演算法則能夠滿足這些具有突發特性的流量。通常,漏桶演算法與令牌桶演算法結合起來為網路流量提供更高效的控制。
三、應用級限流1.限流系統總併發/連線/請求數峰值QPS/TPS
2.限制總資源數資料庫連線池,執行緒池等
3.限制某個介面的總併發/請求數秒殺搶購業務介面
4.限制某個介面的時間窗請求數限制每秒/每分鐘/每天呼叫介面的請求數
平滑限流某個介面的請求數流量速率整形,突發流量整形為平均速度流量,常見的有Guava的RateLimter令牌桶演算法實現。
四、分散式限流實現方案:Redis+Lua
Redis放計數器,Lua寫原子化的指令碼
五、接入層限流nginx的limit_conn模組和limit_req模組,對連線數和請求數進行限制。
參考資料:
《億級流量網站架構核心技術》
出處:https://segmentfault.com/a/1190000039069027