限流詳解


限流的目的是通過對並發訪問/請求進行限速或者一個時間窗口內的請求進行限速來保護系統,將流量削峰防止系統掛掉或雪崩,最終做到有損服務而不是不服務。

4.1 限流算法

  4.1.1 令牌桶算法

  4.1.2 漏桶算法

  4.1.3 計數器限流 比如用Redis的有序集合限流

4.2 應用級限流

  4.2.1 限流總並發/連接/請求數

    當快要超過系統QPS時,進行限流保護,新請求將被丟棄或者放到隊列中

  4.2.2 限流總資源數

    比如數據庫連接和線程,使用池化技術限制總資源數

  4.2.3 限流某個接口的總並發數/請求數

    單獨限制某個高頻接口,使用AtomicLong或者信號量,或者Hystrix的信號量模式

  4.2.4 限流某個接口時間窗請求數

    Guava的Cache統計一定時間窗內的請求次數;Redis的有序集合,score是時間,每次查詢時,將時間窗口之外的節點刪除掉,查詢一下總節點數

  4.2.5 平滑限流某個接口的請求數

    令牌桶和漏桶,以恆定或者相對恆定速率處理請求

4.3 分布式限流

  分布式限流的關鍵是將限流做成原子化,是4.2的分布式場景下的延伸。針對的場景是業務層面的限流。

  4.3.1 Redis+Lua

    時間窗口實現:

    鍵值對設計:比如限制每秒並發量,key取時間戳到秒級別,value存請求累加數。

    判斷的流程:取key,不存在新設置,存在則判斷是否大於上限,沒超過則將累加數加一。過期時間設置1秒多一點。整個判斷寫在lua腳本中。

  4.3.2 Nginx+Lua

4.4 接入層限流

  流量入口處的限流,該層主要目的是:負載均衡、非法請求過濾、請求聚合、緩存、降級、限流、A/B測試、服務質量監控。

  相對於分布式限流,這里的限制不涉及業務層面。

  對於Nginx接入層限流可以使用自帶的兩個模塊,通過指定key,針對key進行限流:

  連接數限流模塊:ngx_http_limit_conn_module。比如限定某IP下的總連接數

  請求限流模塊:ngx_http_limit_req_module。漏桶算法實現,有平滑模式和允許突發模式,比如限定某IP下的總請求數

  OpenRestry提供的Lua限流模塊:lua-retry-limit-traffic

4.5 節流

  防止多個相同事件連續重復執行。

  4.5.1 throttleFirst/throttleLast 在一個時間窗口內,多個重復事件只處理第一個或最后一個。

    書中舉的例子,用戶滾動頁面觸發scroll事件,防止瀏覽器卡頓,多個滾動時間只會執行一次

  4.5.2 throttleWithTimeout  兩個連續時間的先后執行時間不得小於某個時間窗口

    書中舉的例子,關鍵詞自動補全,我們想要一個詞的補全而不是每個字的補全,如果每個字都調用補全接口,先輸入字的補全會很快被下一個字的補全覆蓋

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM