開發與維運

接入層限流之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:
image.png

也可以按照server維度進行限制。

【轉載請註明出處】: https://developer.aliyun.com/article/759546

Leave a Reply

Your email address will not be published. Required fields are marked *