關于服務限流這回事,總算整明白了
?前言
隨著現在微服務、分布式系統的發展,各個服務之間的相互調用越來越復雜。為了保證自身服務的穩定性與高可用,當面對超過自身服務能力的請求調用時,要做一定的限流措施。如同五一、國慶期間的旅游出行、景區爆滿,游客限流。我們的服務面對諸如秒殺、大促、618、雙十一以及可能的惡意攻擊、爬蟲等高并發、大流量的場景也需要做服務限流。
對超出服務處理能力之外的請求進行攔截,對訪問服務的流量進行限制,這就是服務限流。接下來我們就好好談談服務限流這回事兒。
兩種限流方式
常見的限流方式可以分為兩類:基于請求限流和基于資源限流。
- 基于請求限流
基于請求限流指從外部訪問的請求角度考慮限流,常見的方式有兩種。
第一種是限制總量,也就是限制某個指標的累積上限,常見的是限制當前系統服務的用戶總量,例如:某個直播間限制總用戶數上限為100萬,超過100萬后新的用戶無法進入;某個搶購活動商品數量只有100個,限制參與搶購的用戶上限為1萬個,1萬以后的用戶直接拒絕。
第二種是限制時間量,也就是限制一段時間內某個指標的上限,例如1分鐘內只允許10000個用戶訪問;每秒請求峰值最高為10萬。
優點:
- 實現簡單
缺點:
- 實踐中面臨的主要問題是比較難以找到合適的閾值。例如系統設定了1分鐘10000個用戶,但實際上6000個用戶的時候系統就扛不住了;或者達到1分鐘10000用戶后,其實系統壓力還不大,但此時已經開始丟棄用戶訪問了。而且還要考慮硬件相關的因素,例如一臺32核的機器和64核的機器處理能力差別很大,閾值是不同的。
應用:
- 適用于業務功能比較簡單的系統,例如負載均衡系統、網關系統、搶購系統等。
- 基于資源限流
基于請求限流是從系統外部考慮的,而基于資源限流是從系統內部考慮的,也就是找到系統內部影響性能的關鍵資源,對其使用上限進行限制。常見的內部資源包括連接數、文件句柄、線程數和請求隊列等。比如CPU的占用率超過80%的時候就開始拒絕新的請求。
優點:
- 有效地反映當前系統的壓力,更好的進行限流
缺點:
- 難以確定關鍵資源
- 難以確定關鍵資源的閾值,需要在線上逐步調試,持續觀察,直到找到合適的值。
應用:
- 適用于具體的某個服務,比如訂單系統、商品系統等。
四種限流算法
常見的限流算法有4種,它們的實現原理和優缺點各不相同,在實際設計的時候需要根據業務場景來選擇。
- 固定時間窗
固定時間窗算法的實現原理是,統計固定時間周期內的請求量或者資源消耗量,超過限額就會啟動限流,如下圖所示:
優點:
- 實現簡單
缺點:
- 存在臨界點問題。例如上圖中的紅藍兩點只間隔了短短10秒,期間的請求數卻已經達到200,超過了算法規定的限額(1分鐘內處理100)。但是因為這些請求分別來自兩個統計窗口,從單個窗口來看還沒有超出限額,所以并不會啟動限流,結果可能導致系統因為壓力過大而掛掉。
- 滑動時間窗
為了解決臨界點問題,滑動時間窗算法應運而生,它的實現原理是,兩個統計周期部分重疊,從而避免短時間內的兩個統計點分屬不同的時間窗的情況,如下圖所示:
優點:
- 不存在臨界點問題
缺點:
- 相對于固定窗口,復雜度有所提升
- 漏桶算法
漏桶算法的實現原理是,將請求放入“桶”(消息隊列等),業務處理單元(線程、進程和應用等)從桶里拿請求處理,桶滿則丟棄新的請求,如下圖所示:
優點:
- 突發大量流量時丟棄的請求較少,因為漏桶本身有緩存請求的作用
缺點:
- 可以平滑流量,但是無法解決流量突增的問題。
- 桶大小動態調整比較困難,需要不斷的嘗試才能找到符合業務需求的最佳桶大小。
- 無法精確控制流出速度,也就是業務的處理速度。
漏桶算法主要適用于瞬時高并發流量的場景(例如剛才提到的0點簽到、整點秒殺等)。在短短幾分鐘內涌入大量請求時,為了更好的業務效果和用戶體驗,即使處理慢一些,也要做到盡量不丟棄用戶請求。
- 令牌桶算法
令牌桶算法和漏桶算法的不同之處在于,桶中放入的不是請求,而是“令牌”,這個令牌就是業務處理前需要拿到的“許可證”。也就是說,當系統收到一個請求時,先要到令牌桶里面拿“令牌”,拿到令牌才能進一步處理,拿不到就要丟棄請求。
它的實現原理是如下圖所示:
優點:
- 通過控制放入令牌的速率,可以動態調整處理速率,實現更加靈活。
- 可以平滑限流,同時可以容忍突發流量,因為桶里面可以累積一定數量的令牌,當突發流量過來的時候,桶里面有累積的令牌,此時的業務處理速度會超過令牌放入的速度。
缺點:
- 突發大量流量的時候可能丟棄很多請求,因為令牌桶不能累積太多令牌。
- 實現相對復雜。
令牌桶算法主要適用于兩種典型的場景,一種是需要控制訪問第三方服務的速度,防止把下游壓垮,例如支付寶需要控制訪問銀行接口的速率;另一種是需要控制自己的處理速度,防止過載,例如壓測結果顯示系統最大處理TPS是100,那么就可以用令牌桶來限制最大的處理速度。
五種限流策略
- 服務拒絕
當請求流量達到限流閾值時,對多余的請求直接拒絕。
可通過設計實現對指定域名、IP、客戶端、應用、用戶等不同來源的請求進行拒絕。
- 延時處理
通過將多余的請求加入緩存隊列或延時隊列,來應對短期的流量突增,高峰期過后開始將堆積的請求流量逐漸處理。
- 請求分級(優先級)
對不同來源的請求設置優先級,先處理優先級更高的請求。如VIP客戶、重要的業務應用(如交易服務優先級高于日志服務)。
- 動態限流
可以監控系統相關指標、評估系統壓力,通過注冊中心、配置中心等動態調整限流閾值。
- 監控預警&動態擴容
如果有優秀的服務監控系統與自動部署、發布系統,可以通過監控系統自動監測系統運行情況,對短期內服務壓力暴增、流量大幅寫入的情況進行郵件、短信等方式進行預警。
在滿足特定條件下,可自動部署、發布相關服務,起到動態擴容的效果。
三個限流位置
- 接入層限流
可以通過Nginx、API路由網關等對域名或IP進行限流,同時可以攔截非法請求。
- 應用限流
每個服務可以有自己的單機或集群限流措施,也可以調用第三方的限流服務,比如阿里的Sentinel限流框架。
- 基礎服務限流
也可以對基礎服務層進行限流。
- 數據庫:限制數據庫連接、限制讀寫速率
- 消息隊列:限制消費速率(消費量、消費線程)
總結
本文從宏觀角度總結了服務限流的兩種方式,三個可以限流的位置,四種常見的限流算法,五種限流的策略。最后再補充幾句,合理的限流配置,需要了解系統的吞吐量,所以,限流一般需要結合容量規劃和壓測來進行。當外部請求接近或者達到系統的最大閾值時,觸發限流,采取其他的手段進行降級,保護系統不被壓垮。
參考:http://www.studyofnet.com/555653372.html