回覆列表
  • 1 # JAVA前線

    1 限流目的

    限流目的是對系統進行保護。當訪問量激增,超過系統可以承受的流量,則需要把超出的流量擋住,不進行業務邏輯直接返回。

    2 預估系統流量上限

    採用壓測方法。對某個介面進行壓測,逐步調高併發量和持續時間,達到系統瓶頸時(錯誤率高,響應時間長)記錄下併發量,這個值就是當前系統流量上限。

    3 限流方案3.1 系統維度

    從系統維度來看可以分為單機限流和叢集限流兩種方式。

    單機限流是對每一臺機器限流,假設每臺機器限流100QPS,叢集有10臺機器,那麼整個叢集有1000QPS能力。可以使用Guava RateLimiter、Java併發包Semaphore實現單機限流。

    叢集限流是對整個叢集進行限流,比如預估整個叢集能力有1000QPS,還有一種場景是限次,比如整個叢集只能呼叫第三方介面多少次。可以使用Redis實現全侷限流。

    3.2 方法維度

    限流常用方法有以下三種:

    計數器法

    維護一個計數器,這個計數器有一個時間視窗,在當前時間視窗,每當一個新請求到來時,計數器自增,當計數器自增達到設定的上限時,不再提供服務。滑動到下一個時間視窗時,計數器重置。這種方法的特點是簡單,但是在時間視窗臨界點,可能會出現超出流量的問題。

    漏桶演算法

    漏桶演算法強制一個常量的輸出速率而不管輸入資料流的突發性。當輸入空閒時,該演算法不執行任何動作,就像用一個底部開了個洞的漏桶接水一樣,水進入到漏桶裡,桶裡的水透過下面的孔以固定的速率流出。當水流入速度過大會直接溢位。

    令牌桶演算法

    我推薦這種方法。一個容量固定的桶,以一個恆定的速率產生令牌,如果桶內的令牌滿了則多餘的令牌會被丟棄。每當請求進來時,先去桶內拿一個令牌,桶內的令牌拿完了,則必須等待桶內產生令牌才能允許後續的請求(或者直接拒絕)。由於桶內可以堆積一定的令牌(一般為桶容量),所以令牌桶演算法優點是可以允許一定量的流量高峰。

    Guava提供了限流工具RateLimiter基於令牌桶完成限流。也可以透過編寫Lua指令碼透過Redis實現全域性令牌桶。

  • 中秋節和大豐收的關聯?
  • 過年是存錢好還是花錢好?