ngx_http_limit_req_module 模块概述

一、示例配置

http {
    # 定义一个名为 one 的限速区域,10MB 内存,平均速率 1 请求/秒
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    server {
        listen 80;
        server_name example.com;

        location /search/ {
            # 使用 one 区域,允许突发最多 5 次请求,超出的请求会排队延迟处理
            limit_req zone=one burst=5;
        }
    }
}

二、指令详解

1. limit_req_zone

  • 语法

    limit_req_zone <key> zone=<name>:<size> rate=<rate> [sync];
    
  • 上下文http

  • 必需参数

    • <key>:限速键,通常包含变量(如 $binary_remote_addr)。
    • zone=<name>:<size>:共享内存区域名称及大小(如 zone=one:10m)。
    • rate=<rate>:平均允许速率,单位 r/s(请求/秒)或 r/m(请求/分钟),如 1r/s30r/m
  • 可选参数

    • sync(1.15.3+,仅商业版):开启多 worker 进程间限速状态同步。
  • 默认:无

  • 说明

    • 每个 key 在共享内存中占用固定字节(32 位平台 64B,64 位平台 128B),10MB 区域大约可保存 <size> * 1024*1024 / bytes_per_state 条记录。
    • 区域满时淘汰最久未使用状态,若仍不能创建新状态,则直接拒绝请求。
  • 示例

    # 每个 IP 平均 1r/s,区域 one 大小 10MB
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    

2. limit_req

  • 语法

    limit_req zone=<name> [burst=<number>] [nodelay | delay=<number>];
    
  • 上下文http, server, location

  • 参数

    • zone=<name>:指定前面定义的限速区域名称。
    • burst=<number>(默认 0):允许的最大突发请求数(桶大小)。
    • delay=<number>(1.15.7+,默认 0):超过平均速率时可延迟的最大请求数,超过该值即拒绝。
    • nodelay:不延迟,超出突发数即刻拒绝。
  • 默认:无

  • 说明

    • 突发处理:在不超过 burst 时,允许短期内突发放行;超过后依旧按照平均速率放行或拒绝。
    • nodelaydelay 互斥,nodelay 会使任何超过 burst 的请求直接返回错误码(可由 limit_req_status 指令指定)。
  • 示例

    # 允许平均 1r/s,突发最多 5 次,超出突发立即拒绝
    limit_req zone=one burst=5 nodelay;
    
    # 允许平均 1r/s,突发最多 5 次,超出突发但小于 delay 时延迟处理
    limit_req zone=one burst=5 delay=10;
    

3. limit_req_dry_run

  • 语法

    limit_req_dry_run on | off;
    
  • 上下文http, server, location

  • 启用版本:1.17.1+

  • 默认off

  • 说明

    • 干运行模式:不实际限速,只记录“过量”请求在共享内存中的计数,便于评估配置效果而不影响正常流量。
  • 示例

    limit_req zone=one burst=5;
    limit_req_dry_run on;
    

4. limit_req_log_level

  • 语法

    limit_req_log_level info | notice | warn | error;
    
  • 上下文http, server, location

  • 启用版本:0.8.18+

  • 默认error

  • 说明

    • 设置拒绝(REJECTED)及延迟(DELAYED)请求的日志级别。
    • 延迟事件级别比拒绝事件低一级(如 notice 配置下,延迟记录为 info)。
  • 示例

    limit_req_log_level notice;
    

5. limit_req_status

  • 语法

    limit_req_status <code>;
    
  • 上下文http, server, location

  • 启用版本:1.3.15+

  • 默认503

  • 说明

    • 当请求被拒绝(超过突发且非 dry-run)时返回的 HTTP 状态码。
  • 示例

    limit_req_status 429;  # 超速时返回 429 Too Many Requests
    

三、嵌入变量

  • $limit_req_status(1.17.6+)
    该变量记录本次请求的限速结果,可能的取值:

    • PASSED
    • DELAYED
    • REJECTED
    • DELAYED_DRY_RUN
    • REJECTED_DRY_RUN

可在日志格式或后续脚本中引用,例如:

log_format  main  '$remote_addr - $remote_user [$time_local] '
                  '"$request" $status $body_bytes_sent '
                  '"$limit_req_status"';

四、实现原理与注意事项

  1. “漏桶”算法

    • 每个 key 对应一个“桶”,按照固定速率漏出请求令牌;突发请求可瞬时消耗桶内的额外容量(burst)。
    • 超出 burst 后的请求,若设置了 delay,则在令牌不可用时排队等待;若未设置或 nodelay,则直接拒绝。
  2. 状态管理

    • 限速状态保存在共享内存,支持多 worker 进程共享;商业版可开启 sync 实现跨机同步。
    • 区域大小与 key 数量需平衡:区过小会导致频繁 LRU 淘汰,大区则浪费内存。
  3. 配置继承

    • limit_req 系指令可置于 httpserverlocation 三级;若某级别未显式配置,则继承父级。
  4. 干运行(dry run)

    • 在流量高峰或生产环境初次调优时,可先启用 limit_req_dry_run,仅记录限速,无实际影响。
  5. 状态暴露(商业版)

    • 从 1.17.7 起,商业版可通过 API 查看或重置共享内存区的统计信息,便于运维监控与排查。

五、总结

ngx_http_limit_req_module 通过灵活的突发控制与延迟/拒绝策略,为 Nginx 提供了高效的流量限速能力。结合 dry-run、日志级别与内置变量,可在保证服务可用性的同时,抵御突发或恶意请求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello.Reader

请我喝杯咖啡吧😊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值