簡單學習限流
目的:
通過對並發訪問和請求進行限速或者一個時間窗口內的請求進行限速來保護系統的可用性,一旦達到限制速率就可以拒絕服務(友好定向到錯誤頁或告知資源沒有了),排隊或者等待(比如秒殺,評論,下單),降級(返回默認數據)。
通過壓測的手段找到每個系統的處理峰值,然后通過設定峰值閾值,來防止當系統過載時,通過拒絕處理過載的請求來保障系統 可用性,同時也應該根據系統的吞吐量,響應時間,可用率來動態調整限流閾值。
分類:
- 限制總並發數---數據庫連接池,線程池
- 限制瞬時並發數---nginx的limit_conn模塊,用來限制瞬時並發連接數
- 限制時間窗口內的平均速率---guava的RateLimiter,nginx的limit_req模塊,限制每秒平均速率
- 其他---限制遠程接口調用速率,限制MQ消費速率,另外,還可以根據網絡連接數,網絡流量,CPU或內存負載等來限流。
算法:
- 滑動窗口協議---改善吞吐量的技術
- 漏桶---強制限制數據的傳輸速率,限制的流出速率
- 令牌桶---(控制(流入)速率類型的限流算法)系統以恆定的速度往桶中放入令牌,如果請求需要被處理,則需要先從桶中獲取一個令牌,當桶中沒有令牌可取,則拒絕服務。當平時處理速率小於桶中令牌的速率,那么在突發流量時桶內有堆積可以有效預防。
令牌桶和漏桶的對比:
- 令牌桶是按照固定的速率往桶中添加令牌,請求是否被處理需要看桶中令牌是否足夠,當令牌數為0,則拒絕新的請求
- 漏桶則是按照常量固定速率流出請求,流入請求速率任意,當流入請求數累計到漏桶容量時,則新的請求被拒絕。
- 令牌桶限制的是平均流入速率(允許突發請求,只要有令牌就可以處理,一次拿3個令牌,4個令牌),並允許一定程度並發流量
- 漏桶限制的是常量流出速率(即流出速率是一個固定常量值,比如都是1的速率流出,而不能一次是1,下次是2),從而平滑的解決了突發流入速率
- 兩個算法實現可以一樣,但是方向是相反的,對於相同的參數得到的限流效果是一樣的。
- 計數器(***)---通過控制時間段內的請求次數,限制總並發數,比如數據庫連接池大小,線程池大小,秒殺並發數都是計數器的用法。只要全局總請求數或者一段時間內的請求數達到設定閾值,則進行限流。對比上面的速率限流,該算法是總數量限流。
策略:
- Nginx接入層限流
- 對某個key對應的總的網絡連接數進行限流,可以按照一定的規則如賬號,IP,系統調用邏輯等在Nginx層面做限流---連接數限流模塊:limit_conn
- 對某個key對應的請求的平均速率進行限流,兩種:平滑模式和允許突發模式---請求限流模塊:limit_req
- 應用級限流
- 限流總並發/連接/請求數---設定合適的閾值(tomcat,redis,mysql等都有類似配置)
- 限流總資源數---數據庫連接池,線程池
- 限流接口的總並發/請求數---適用於可降級的業務場景,可以讓用戶友好接受。可以使用計數器方式實現。
- 限流接口的時間窗口請求數---使用計數器方式
- 平滑限流接口請求數(應對突發流量)---令牌桶/漏桶
《億級流量網站架構核心技術》