在資源有限的情況下,遇到突發流量(如雙十一)或系統 rt 劇增,為了保證系統不被拖垮引起更大規模的雪崩,必須進行限流。也就是說限流是系統的自我保護。限流本質上是根據系統處理能力,限制單位時間內處理的請求數量。
這裡的視窗是乙個時間視窗,比如把一分鐘劃分為 6 個視窗,則每個視窗的時間範圍是 10 秒。通過移動視窗,統計視窗期內流量,可以實現視窗期的限流。但是滑動視窗存在精度問題,在精度範圍內統計到的視窗期流量可能在限流範圍內,但進一步細分就會看到仍有突增流量。
滑動視窗時間範圍越小,就越平滑,限流的效果越精確,但時間細分的粒度受到客觀限制。
漏桶演算法,英文名 leaky bucket,是網路中流量整形(traffic shaping)和速率限制(rate limiting)常用的一種演算法。漏桶演算法調控了訪問流量,使得突發流量可以被整形、去毛刺,為系統提供穩定的訪問流量。如果漏桶溢位,請求就會被丟棄。
桶以固定的速率流出流量,無論水龍頭進入的流量是多少,都不改變流出速率。上圖中,水龍頭處存在突發流量,一共進入 30mb 資料,分布不均勻,對系統有衝擊。經過漏桶演算法處理,漏桶以 3 mbps 速率持續流出資料,為系統做了很好的緩衝。
漏桶演算法中,如果桶未滿,可以持續接收流量;如果桶已滿,流量溢位,後續的流量將無法入桶,會被丟棄。漏桶演算法限制的是流出速率,無論流入是多少,都能保證後續系統的請求是平穩的。後續系統感知的流量相對固定,但可能在系統仍有能力處理更多流量的時候,也會被漏桶限制住。
令牌桶演算法,英文名 token bucket,也是網路中流量整形或速率限制常用的一種演算法。令牌桶演算法以乙個恆定的速率向桶裡放入令牌,如果有新的請求進來希望進行處理,則需要先從桶裡獲取乙個令牌,當桶裡沒有令牌可取時,則拒絕服務。令牌桶演算法限制的是流入速率,允許一定規模的突增流量,最大速率受限於桶的容量和令牌生成速率。可以支援一定程度的突發流量,更適合具有突發特性的流量。
令牌桶演算法的簡單描述如下:
使用自適應閾值可以動態調整限流,通過執行中不斷試探,最終可以在系統處理能力和限流之間找到乙個動態平衡。既能最大限度利用系統處理能力,又能確保系統穩定性。目前比較簡單的自定義演算法是參考 tcp 擁塞演算法的斜率演算法。斜率演算法設定乙個基準值,可以結合應用的 load、cpu 使用率、總體平均 rt、入口 qps 和併發執行緒數等幾個維度的監控指標評估系統負載,負載高了降低限流閾值,負載低了提高限流閾值。
目前比較簡單的方案是使用平均 rt 計算斜率,公式為
gradient =(rttnoload / rttactual)
newlimit = currentlimit×gradient + queuesize
其中,rttnoload 表示無負載時的 rt,rttactual 表示當前實際 rt。gradient 小於 1 表示負載偏高,大於 1 表示負載偏低。經過一段時間的試探,就能把系統流量控制在合理範圍。
現代網路服務通常都有多台機器,需要對集群做限流。目前使用比較廣泛的方案是 redis 。滑動視窗可以使用 redis 記錄時間和訪問次數;redis-cell 是乙個實現漏桶演算法的分布式限流擴充套件模組,使用非常方便。
推薦閱讀
git 工作原理
mybatis 一級二級和自定義快取
mysql innodb和myisam區別總結
快取擊穿、穿透、雪崩簡單總結
沒有共情能力的程式設計師不是好產品經理
限流和限流演算法
目錄 一 什麼是限流 二 為什麼需要限流 三 那些場景需要用到限流 3.1 對外服務 3.2 對內服務 四 限流演算法 4.1 計數器演算法 4.2 漏桶演算法 4.3 令牌桶演算法 限流其實是指當系統資源不夠,不足以應對大量請求,即系統資源與訪問量出現矛盾的時候,我們為了保證有限的資源能夠正常服務...
服務限流演算法
業務 中的邏輯限流 按照服務的呼叫方,可以分為以下幾種型別服務 1 與使用者打交道的服務 比如web服務 對外api,這種型別的服務有以下幾種可能導致機器被拖垮 2 對內的rpc服務 乙個服務a的介面可能被bcde多個服務進行呼叫,在b服務發生突發流量時,直接把a服務給呼叫掛了,導致a服務對cde也...
Redis 限流演算法
判斷有限時間內的數量是否超過限制上線 date default timezone set prc class limitelse elseelse else 有問題,併發上來,一直就允許5個,但是利用 pipeline 保證了各個client之間的原子性 function isactionallow...