每一個API接口都是有訪問上限的,當訪問頻率或者併發量超過其承受範圍時候,咱們就必須考慮限流來保證接口的可用性或者降級可用性。即接口也須要安裝上保險絲,以防止非預期的請求對系統壓力過大而引發的系統癱瘓。算法
一般的策略就是拒絕多餘的訪問,或者讓多餘的訪問排隊等待服務,或者引流。網絡
若是要準確的控制QPS,簡單的作法是維護一個單位時間內的Counter,如判斷單位時間已通過去,則將Counter重置零。此作法被認爲沒有很好的處理單位時間的邊界,好比在前一秒的最後一毫秒裏和下一秒的第一毫秒都觸發了最大的請求數,將目光移動一下,就看到在兩毫秒內發生了兩倍的QPS。併發
經常使用的更平滑的限流算法有兩種:漏桶算法和令牌桶算法。spa
漏桶(Leaky Bucket)算法思路很簡單,水(請求)先進入到漏桶裏,漏桶以必定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),而後就拒絕請求,能夠看出漏桶算法能強行限制數據的傳輸速率。示意圖以下:blog
可見這裏有兩個變量,一個是桶的大小,支持流量突發增多時能夠存多少的水(burst),另外一個是水桶漏洞的大小(rate)。接口
由於漏桶的漏出速率是固定的參數,因此,即便網絡中不存在資源衝突(沒有發生擁塞),漏桶算法也不能使流突發(burst)到端口速率。所以,漏桶算法對於存在突發特性的流量來講缺少效率。圖片
令牌桶算法(Token Bucket)和 Leaky Bucket 效果同樣但方向相反的算法,更加容易理解。資源
隨着時間流逝,系統會按恆定1/QPS時間間隔(若是QPS=100,則間隔是10ms)往桶裏加入Token(想象和漏洞漏水相反,有個水龍頭在不斷的加水),若是桶已經滿了就再也不加了。新請求來臨時,會各自拿走一個Token,若是沒有Token可拿了就阻塞或者拒絕服務。it
令牌桶的另一個好處是能夠方便的改變速度。一旦須要提升速率,則按需提升放入桶中的令牌的速率。通常會定時(好比100毫秒)往桶中增長必定數量的令牌,有些變種算法則實時的計算應該增長的令牌的數量。class