在當下互聯網高並發時代中,項目往往會遇到需要限制客戶端連接的需求。我們熟知的 Nginx 就提供了有這樣的功能,可以簡單的實現對客戶端請求頻率,並發連接和傳輸速度的限制….
Nginx 限流
Nginx
為我們提供了請求限制模塊(ngx_http_limit_req_module
)、基於令牌桶算法的流量限制模塊(ngx_stream_limit_conn_module
),可以方便的控制令牌速率,自定義調節限流,實現基本的限流控制…
請求限制
請求限制的功能來自於 ngx_http_limit_req_module
模塊。使用它需要首先在 http 配置段中定義限制的參照標准和狀態緩存區大小。
limit_req_zone
只能配置在 http
范圍內;
$binary_remote_addr
表示客戶端請求的IP地址;
mylimit
自己定義的變量名;
rate
請求頻率,每秒允許多少請求;
limit_req
與 limit_req_zone
對應,burst
表示緩存住的請求數,也就是任務隊列。
下面的配置就是定義了使用客戶端的 IP 作為參照依據,並使用一個 10M 大小的狀態緩存區。結尾的 rate=1r/s 表示針對每個 IP 的請求每秒只接受一次。
10M 的狀態緩存空間夠不夠用呢?官方給出的答案是 1M 的緩存空間可以在 32 位的系統中服務 3.2 萬 IP 地址,在 64 位的系統中可以服務 1.6 萬 IP 地址,所以需要自己看情況調整。如果狀態緩存耗光,后面所有的請求都會收到 503(Service Temporarily Unavailable) 錯誤。
腳本代碼
1 |
# 定義了一個 mylimit 緩沖區(容器),請求頻率為每秒 1 個請求(nr/s) |
測試代碼
為了方便此處提供 JAVA、AB
兩種測試代碼..
1 |
|
1 |
package com.battcn.limiting; |
測試日志
此處提供 AB 測試結果 JAVA 的日志就不貼了,5個請求其中一個請求是有問題的,出問題的那個就是被拒絕請求的…
1 |
[root@localhost myconf]# ab -n 5 -c 5 http://192.168.0.133:70/index |
並發限制
Nginx 並發限制的功能來自於 ngx_http_limit_conn_module
模塊,跟請求配置一樣,使用它之前,需要先定義參照標准和狀態緩存區。
limit_conn_zone
只能配置在 http
范圍內;
$binary_remote_addr
表示客戶端請求的IP地址;
myconn
自己定義的變量名(緩沖區);
limit_rate
限制傳輸速度
limit_conn
與 limit_conn_zone
對應,限制網絡連接數
下面的配置就是定義了使用客戶端的 IP 作為參照依據,並使用一個 10M 大小的狀態緩存區。限定了每個IP只允許建立一個請求連接,同時傳輸的速度最大為 1024KB
腳本代碼
1 |
# 定義了一個 myconn 緩沖區(容器) |
說點什么
請求限流方面自己寫一個簡單的 Spring Boot
程序部署到服務器配置好 Nginx 映射即可,並發限流弄一個大文件下載,或者讓自己服務接口在內部休眠一定時間就能測試出效果….
參考文獻
- ngx_http_limit_req_module http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
- ngx_http_limit_conn_module http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
- ngx_http_core_module http://nginx.org/en/docs/http/ngx_http_core_module.html