1. 程式人生 > >限流及常用算法

限流及常用算法

時間 9.png 平滑 窗口 接口 服務 aop 實現思路 理解

適用場景

當系統需要應用高並發的沖擊時,一個最常用的策略是使用緩存提高系統容量,這通常是效果最好的方式,但如論如何提升系統容量,都會存在一個QPS/TPS的閾值,超過該閾值則認為系統不再穩定,因此需要采取措施屏蔽掉這些請求,達到系統穩定可用的目的。 實現這一目標的常見策略為限流: 限流,顧名思義就是限制流量的意思,既然支撐不了,那就不要死撐,而是采用拒絕服務、排隊、降級等手段保證核心功能穩定可用。 限流一般分為兩個層次:
  • 系統級
    • 現在系統龐大和復雜,系統級限流也即在系統入口處,根據限流策略,限流總並發,連接,請求數等,通常使用Nginx實現。
  • 應用級
    • 可以限流應用級的並發,總資源數,某時間窗口訪問數等,實現起來非常靈活,主要思想基於令牌桶,漏桶等算法

令牌桶算法

一個固定大小存放令牌的桶,按照固定的速率往桶中添加令牌,如果到達一個請求,則從桶中拿走一個另外,如果桶中沒有令牌,則請求返回或排隊。令牌桶可以應用瞬時流量沖擊(令牌桶滿的時候) 技術分享圖片 技術分享圖片

漏桶算法

漏桶算法也很好理解,桶的底部有一固定大小的孔,因此可以以固定流量流出,桶的頂部可以以任意速率向其中流入,直到桶滿。漏桶算法常用於流量整形(平滑流量),無論外部請求如何密集,系統以固定速率處理,保證系統不會被瞬時流量壓垮。 技術分享圖片 技術分享圖片 除此之外,也可以使用計數器進行限流,主要用於限制總並發數,如數據庫連接池、線程池等都是計數器的用法,只要全局流量達到一定閾值則進行限流。

實現思路

由於我們的應用基於Spring框架實現,對接口級別的限流很容易想到使用切面來實現。主要思路有:
  • 根據配置文件,采用單例模式,構建每個受控方法的令牌桶對象
  • 使用AOP攔截對Controller層方法的訪問
  • 檢查令牌桶中是否由令牌,如果沒有則返回,有則繼續
技術分享圖片 技術分享圖片

限流及常用算法