天天看點

接入層限流之ngx_http_limit_req_module

【轉載請注明出處】: https://developer.aliyun.com/article/759546 ngx_http_limit_req_module子產品是Nginx提供的基于漏桶算法實作的請求限流子產品,用于對指定KEY對應的請求進行限流,比如按照IP次元限制請求速率。 ngx_http_limit_req_module官方文檔 配置示例

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    limit_conn_log_level error;
    limit_conn_status 503;
    ...
    server {
    ...
    location /limit {
        limit_req zone=one burst=5 nodelay;
    }           
  • limit_req:配置限流區域、桶容量(突發容量,預設0)、是否延遲模式(預設延遲);
  • limit_req_zone:配置限流KEY、及存放KEY對應資訊的共享記憶體區域大小、固定請求速率;此處指定的KEY是“$binary_remote_addr”表示IP位址;固定請求速率使用rate參數配置,支援10r/s和60r/m,即每秒10個請求和每分鐘60個請求,不過最終都會轉換為每秒的固定請求速率(10r/s為每100毫秒處理一個請求;60r/m,即每1000毫秒處理一個請求)。
  • limit_conn_status:配置被限流後傳回的狀态碼,預設傳回503;
  • limit_conn_log_level:配置記錄被限流後的日志級别,預設error級别。

limit_req的主要執行過程如下所示:

  1. 請求進入後首先判斷最後一次請求時間相對于目前時間(第一次是0)是否需要限流,如果需要限流則執行步驟2,否則執行步驟3;
  2. 如果沒有配置桶容量(burst),則桶容量為0;按照固定速率處理請求;如果請求被限流,則直接傳回相應的錯誤碼(預設503);

    如果配置了桶容量(burst>0)且是延遲模式(沒有配置nodelay);如果桶滿了,則新進入的請求被限流;如果沒有滿則請求會以固定平均速率被處理(按照固定速率并根據需要延遲處理請求,延遲使用休眠實作);

如果配置了桶容量(burst>0)且非延遲模式(配置了nodelay);不會按照固定速率處理請求,而是允許突發處理請求;如果桶滿了,則請求被限流,直接傳回相應的錯誤碼;

  1. 如果沒有被限流,則正常處理請求;
  2. Nginx會在相應時機進行選擇一些(3個節點)限流KEY進行過期處理,進行記憶體回收。

Nginx配置

定義IP次元的限流區域:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
limit_conn_log_level info; 
limit_conn_status 503;

server {
    listen       8000;
    server_name  localhost;

    location /limit {
       limit_req zone=one burst=5 nodelay;
       proxy_pass http://127.0.0.1:8081; 
    }

}           

每秒1個請求,桶容量為5,如果桶滿了直接拒絕新請求,且每秒最多1個請求,桶按照固定1秒的速率以nodelay模式處理請求。

使用AB測試工具進行測試,并發數為5個,總的請求數為30個:

ab -n 30 -c 5 http://127.0.0.1:8000/limit/test           

檢視nginx access.log:

也可以按照server次元進行限制。

繼續閱讀