統一流控服務開源-1:場景&業界作法&算法篇

最近團隊在搞流量安全控制,爲了應對不斷增大的流量安全風險。Waf防禦能作一下接入端的攔截,可是實際流量會打到整個分佈式系統的每一環:Nginx、API網關、RPC服務、MQ消息應用中心、數據庫。瞬間的大流量對系統的總體的衝擊仍是很大的,一些連鎖反應時刻刺激着咱們的神經!因此,咱們要設計開發咱們本身的流控中心。解決咱們的系統痛點問題。nginx

1、首先,咱們從系統需求提及:git

1. 接入點IOT設備,瞬間批量上線&離線:幾十萬設備同時離線、上線後,帶來的三遙數據、狀態數據,瞬間打到後端。雖然有MQ扛了一層,可是MQ消費端是併發處理的,後端業務扛不住了github

2. 大型促銷發券活動,幾十萬用戶瞬間異步發出上百萬張優惠券。算法

3. API網關,時候接受第三方合做夥伴的定時訪問,請求密集、數據訪問大,後端RPC服務疲於應對。數據庫

4. DB層,上述場景最後60%的請求會落到DB端,磁盤、CPU壓力大後端

5. Redis,大範圍訪問Redis中的緩存數據,TPS瞬間就上去了。緩存

 經過分析以上這些問題,都是因爲瞬間流量過大形成,所以必須對大流量進行控制。流量控制越靠近鏈路開端,帶來的效果越明顯。安全

2、在設計流控以前,咱們要看一下互聯網業績怎麼作的!網絡

咱們借鑑了阿里的作法,畢竟做爲雲廠商和雙11締造者,流控方面的經驗仍是通過實際業務驗證的!併發

總結一下:

  • 流控說白了就是控制速率,在系統各個層面防止被大流量打爆
  • 在系統的各個層面,流控策略和方式是不一樣的,API網關的、RPC服務的、MQ的
  • 流量控制的維度能夠是全局的、進程的、請求來源、用戶及自定義維度
  • 流量控制是動態的,應該根據系統的「併發特色」動態調配、控制
  • 流控的根本目的就是保證系統的高可用性。

總結梳理了業界流量控制的作法以後,咱們再看一下具體的流控算法及實現!

3、流控算法及實現

目前業界的流控算法的就這麼幾種:漏桶、令牌桶、計數器,咱們一一展開介紹一下。

1. 漏桶(Leaky Bucket)算法

水(請求)先進入到漏桶裏,漏桶以必定的速度出水(接口有響應速率),

當水流入速度過大會直接溢出(訪問頻率超過接口響應速率), 而後就拒絕請求,

能夠看出漏桶算法能強行限制數據的傳輸速率.

有兩個變量:

  • 一個是桶的大小,支持流量突發增多時能夠存多少的水(burst),
  • 另外一個是水桶漏洞的大小(rate)。

漏桶算法的問題:

  • 水滿了直接不讓進、丟棄
  • 桶容量問題
  • 漏出速度控制問題

2. 令牌桶算法(Token Bucket)

 

隨着時間流逝,系統會按恆定1/QPS時間間隔(若是QPS=100,則間隔是10ms)

往桶裏加入Token(想象和漏洞漏水相反,有個水龍頭在不斷的加水),

若是桶已經滿了就再也不加了. 新請求來臨時,

會各自拿走一個Token,若是沒有Token可拿了就阻塞或者拒絕服務.

令牌添加速度支持動態變化,實時控制處理的速率.

令牌桶算法的問題:

  • 令牌滿了,請求沒法處理
  • 桶容量問題
  • 令牌添加速度控制問題

3. 漏桶和令牌桶算法對比

  • 令牌桶是按照固定速率往桶中添加令牌,請求是否被處理須要看桶中令牌是否足夠,當令牌數減爲零時則拒絕新的請求;
  • 漏桶則是按照常量固定速率流出請求,流入請求速率任意,當流入的請求數累積到漏桶容量時,則新流入的請求被拒絕;
  • 令牌桶限制的是平均流入速率(容許突發請求,只要有令牌就能夠處理,支持一次拿3個令牌,4個令牌),並容許必定程度突發流量;
  • 漏桶限制的是常量流出速率(即流出速率是一個固定常量值,好比都是1的速率流出,而不能一次是1,下次又是2),從而平滑突發流入速率;
  • 令牌桶容許必定程度的突發,而漏桶主要目的是平滑流入速率;
  • 兩個算法實現能夠同樣,可是方向是相反的,對於相同的參數獲得的限流效果是同樣的。

4. 計數器

主要用來限制總併發數,好比數據庫鏈接池、線程池、併發數;只要全局總請求數超過設定的閥值則進行限流,是簡單粗暴的總數量限流,而不是平均速率限流。

  • 限制總併發數(好比數據庫鏈接池、線程池)
  • 限制瞬時併發數(如nginx的limit_conn模塊,用來限制瞬時併發鏈接數)
  • 限制時間窗口內的平均速率(如Guava的RateLimiter、nginx的limit_req模塊,限制每秒的平均速率)
  • 限制遠程接口調用速率
  • 限制MQ的消費速率。
  • 能夠根據網絡鏈接數、網絡流量、CPU或內存負載等來限流

總結一下:

從流控算法上看,主要有三個核心要素:

  • 可用容量
  • 速率控制
  • 容量打滿後的處理策略:丟棄 or 阻塞

流控算法只是流量控制中核心的一環,並非所有。實際應用上,須要結合實際的業務場景,採用適合的流控算法實現流量控制

4、流控中心設計

經過上面需求分析、業界對標&對比、流控算法對比,咱們規劃了流控中心的產品特性,在此基礎上完成一個V1.0版本的流控框架實現,同時準備開源出去,讓更多的人能夠直接使用。

管理時(設計時):

  • 提供統一的流控策略定義,流控策略中能夠指定使用具體控制方式,支持QPS、指定時間內訪問量、併發數、延遲時間四種控制方式
    • 支持對API網關服務、RPC服務、MQ等不一樣的主體,綁定不一樣的流控策略和閾值。
    • 對於API網關服務,支持按服務、來源、用戶、集羣、進程設置QPS流量控制策略,同時支持按指定時間範圍(分鐘、小時、天)設置訪問次數對應的流控策略。
    • 對於RPC服務,支持按服務、集羣、進程設置QPS流量控制策略,同時支持按指定時間範圍(分鐘、小時、天)設置訪問次數對應的流控策略。
    • 對於MQ,支持按隊列、集羣、進程設置消息消費的併發流量控制策略,同時支持延遲消費控制策略。
  • 觸發流控策略後,支持一種或者多種處理策略:請求失敗、請求等待、預警等
  • 流控策略和閾值支持動態調配,經過配置中心實時同步到各個流控模塊,配置動態實時生效。
  • 提供統一的流控日誌查看功能,支持根據流控主體、時間實時查詢流控觸發狀況。

運行時:

  • 提供可獨立運行的限流模塊程序,Host在各種服務容器(API網關、RPC服務框架、MQ)中獨立運行
  • 運行時支持對QPS、指定時間內訪問量、併發數、延遲時間四種流量控制方式,根據流控策略的定義實時控制流量。
  • 提供對應用集羣(全局)類的流控管理及應用進程(進程級)的流控管理
  • 觸發流控後,支持實時將監控、預警信息實時推送到監控預警平臺
  • 流控策略和閾值調整後,經過配置中心實時同步到各個限流模塊程序,實時生效。

這是目前咱們流控中心大體的規劃和整理,其實技術原型代碼咱們已經寫出來了,昨天完成UT經過了,下一篇博客咱們將把這個流控框架一點點分享給你們。

提早劇透一下,咱們借鑑了Git的RateLimiters

https://github.com/robertmircea/RateLimiters

 

周國慶

2018/5/16

相關文章
相關標籤/搜索