常用的限流算法

參考文章:

https://juejin.im/post/5ec1dd5f5188256d77633faf?utm_source=gold_browser_extension

1.限流分類

  1. 合法性驗證限流:比如驗證碼、IP 黑名單等,這些手段可以有效的防止惡意攻擊和爬蟲採集;
  2. 容器限流:比如 Tomcat、Nginx 等限流手段,其中 Tomcat 可以設置最大線程數(maxThreads),當併發超過最大線程數會排隊等待執行;而 Nginx 提供了兩種限流手段:一是控制速率,二是控制併發連接數;
  3. 服務端限流:比如我們在服務器端通過限流算法實現限流,此項也是我們本文介紹的重點。

合法性驗證限流爲最常規的業務代碼,就是普通的驗證碼和 IP 黑名單系統,本文就不做過多的敘述了,我們重點來看下後兩種限流的實現方案:容器限流和服務端限流。

tomcat限流:

Tomcat 8.5 版本的最大線程數在 conf/server.xml 配置中,如下所示:

<Connector port="8080" protocol="HTTP/1.1"
          connectionTimeout="20000"
          maxThreads="150"
          redirectPort="8443" />
其中 maxThreads 就是 Tomcat 的最大線程數,當請求的併發大於此值(maxThreads)時,請求就會排隊執行,這樣就完成了限流的目的。
小貼士:maxThreads 的值可以適當的調大一些,此值默認爲 150(Tomcat 版本 8.5.42),但這個值也不是越大越好,要看具體的硬件配置,需要注意的是每開啓一個線程需要耗用 1MB 的 JVM 內存空間用於作爲線程棧之用,並且線程越多 GC 的負擔也越重。最後需要注意一下,操作系統對於進程中的線程數有一定的限制,Windows 每個進程中的線程數不允許超過 2000,Linux 每個進程中的線程數不允許超過 1000。

Nginx 提供了兩種限流手段:一是控制速率,二是控制併發連接數。

控制速率

我們需要使用 limit_req_zone 用來限制單位時間內的請求數,即速率限制,示例配置如下:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit;
    }
}
以上配置表示,限制每個 IP 訪問的速度爲 2r/s,因爲 Nginx 的限流統計是基於毫秒的,我們設置的速度是 2r/s,轉換一下就是 500ms 內單個 IP 只允許通過 1 個請求,從 501ms 開始才允許通過第 2 個請求。

速率限制升級版 

上面的速率控制雖然很精準但是應用於真實環境未免太苛刻了,真實情況下我們應該控制一個 IP 單位總時間內的總訪問次數,而不是像上面那麼精確但毫秒,我們可以使用 burst 關鍵字開啓此設置,示例配置如下:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit burst=4;
    }
}

 控制併發數

利用 limit_conn_zone 和 limit_conn 兩個指令即可控制併發數,示例配置如下:
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}
其中 limit_conn perip 10 表示限制單個 IP 同時最多能持有 10 個連接;limit_conn perserver 100 表示 server 同時能處理併發連接的總數爲 100 個。
只有當 request header 被後端處理後,這個連接才進行計數。

服務端限流

服務端限流需要配合限流的算法來執行,而算法相當於執行限流的“大腦”,用於指導限制方案的實現。

有人看到「算法」兩個字可能就暈了,覺得很深奧,其實並不是。算法就相當於操作某個事務的具體實現步驟彙總,其實並不難懂,不要被它的表象給嚇到哦~

限流的常見算法有以下三種:

  1. 時間窗口算法
  2. 漏桶算法
  3. 令牌算法

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章