服務器端限流保護


之前開發一個視頻聊天室服務,碰到許多服務器端高並發性能的問題,所以進行了一些這方面的學習。服務器端在收到客戶端過多的請求時,往往會因為過高的cpu或者內存消耗而宕掉。這就有一個原則是服務端要能自我保護,寧可提供受損的服務,也不能不提供服務。在開發高並發系統時有三把利器來保護系統:緩存降級限流

緩存的目的是提升系統訪問速度和增大系統能處理的容量。項目中有很多地方用到了緩存。其中一個場景是,客戶端會上傳一個信令表明身份,而這個信令有專門的服務來維護,我們就需要拿着這個信令調用那個服務的http接口來驗證,當並發較多時,http請求就有可能擁堵。考慮到這個信令的存活時間較長,就可以在redis中做一下緩存,定期清理。這樣就減少了http請求次數。

降級是當服務出問題或者影響到核心流程的性能時,需要暫時屏蔽掉一些服務,待高峰或者問題解決后再打開。這個方法基本上每一個服務都用到了,高峰時或者cpu、內存占用較高時,減少日志記錄、主動拒絕一些請求等等。

限流的目的是通過對並發訪問/請求進行限制或者一個時間窗口內的請求進行限速來保護系統,一旦達到限制速率則可以拒絕服務或者排隊等待。

令牌桶算法

令牌桶算法是一個存放固定容量令牌的桶,按照固定速率往桶里添加令牌。簡單描述如下:

  • 假設限制2r/s,則按照500ms的固定速率往桶中添加令牌;
  • 同種最多存放b個令牌,當桶滿時,新添加的令牌被丟棄或拒絕;
  • 當n個請求到來時,從同種刪除n個令牌,接着處理請求;
  • 如果桶中的令牌不足n個,則拒絕后面的部分

令牌桶

漏桶算法

漏桶作為計量工具時,可以用於流量整形和流量控制。簡單描述如下:

  • 一個固定容量的漏桶,按照常量固定速率流出水滴;
  • 如果桶是空的,則不需要流出水滴;
  • 可以以任意的速率流入水滴;
  • 如果流入水滴超出了桶的容量,則流入的水滴溢出,被丟棄。

漏桶

對比這兩個算法

  • 令牌桶是按照固定速率往桶中添加令牌,請求是否被處理需要看桶里令牌是否足夠,當令牌數是零時拒絕新的請求。
  • 漏桶是按照常量固定速率流出請求,流入請求速率任意,當流入的請求數量累計到漏桶容量時,則新流入的請求被拒絕。
  • 令牌桶限制的是單位時間內的平均流入速率,但是允許突發請求
  • 漏桶限制的是流出速度,也就是處理速度,碰到突發請求,也是按固定速率處理這些請求,平滑突發流入速率

我們這次優化只用到了漏桶算法。其實實現很簡單,就是用到一個隊列。隊列的一端不斷添加請求,另一端按照固定的速率,例如每秒1個,來從隊列中讀取請求處理。如果隊列滿了,可以選擇一種策略來處理新來的請求,一是直接丟棄新請求,二是覆蓋舊的請求。這個隊列也可以改為用棧來實現,具體情況具體分析。

計數器限流

主要用來限制總並發數,對全局總請求數或者單位時間內的總請求數進行限流。這個方法比較簡單。

應用級限流

  • 限制總並發/連接/請求數。例如Tomcat、Nginx、Redis可以對線程數、連接數做限制。
  • 限制總資源數。如果有的資源是稀缺自然,而且可能有多個系統都會使用它,那么需要限制應用。最常用的是池化技術,線程池或者連接池。
  • 限流某個接口的總並發/請求數。在Java中可以用AtomicLong進行計數限制。
  • 限流某個接口的時間窗請求數。這和上面的相似,可以用一個計數器進行限制。
  • 平滑限流某個接口的請求數。上面的兩種方法都不能很好的應對突發請求,但有時候會需要對突發請求做一些平滑整形。這時候可以用令牌桶或者漏桶算法。

分布式限流

分布式限流最關鍵的是講限流服務做成原子化,而解決方案可以使用redis+lua或者nginx+lua。我對nginx不熟,而且redis性能很好,所以偏向於使用redis。

local key = KEYS[1] --限流KEY(一秒一個)
local limit = tonumber(ARGV[1])        --限流大小
local current = tonumber(redis.call('get', key) or "0")
if current + 1 > limit then --如果超出限流大小
   return 0
else if current == 1 then --設置2秒過期
    redis.call("INCRBY", key, "1")
    redis.call("EXPIRE", key, "2")
else  --請求數+1
   redis.call("INCRBY", key,"1")
   return 1
end

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM