首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Nginx 限流配置详解:limit_req 的 burst 与 nodelay,以及 limit_conn 的搭配

Nginx 限流配置详解:limit_req 的 burst 与 nodelay,以及 limit_conn 的搭配

原创
作者头像
一只特立独行的兔先生
发布于 2026-11-01 06:28:32
发布于 2026-11-01 06:28:32
1410
举报

背景

接口被脚本刷、登录页被撞库、某个客户端突发大量请求拖垮后端,这些场景都可以先在 Nginx 层做限流。Nginx 提供两个常用模块:limit_req(限制请求速率)和 limit_conn(限制并发连接数)。参数里最容易搞混的是 burst 和 nodelay,本文用例子说清楚。

一、limit_req:限制请求速率

先在 http 块定义共享内存区,再在 location 中引用:

代码语言:nginx
复制
http {
    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
    limit_req_status 429;

    server {
        location /api/ {
            limit_req zone=perip burst=20 nodelay;
            proxy_pass http://backend;
        }
    }
}

各项含义:

  • $binary_remote_addr:以客户端 IP 为限流的键,比 $remote_addr 占用内存更小。
  • zone=perip:10m:区域名与共享内存大小。官方文档给出的估算是 1MB 大约可存放 1.6 万个状态,具体以实际版本和平台为准。区域满了之后新请求会被拒绝,要按客户端数量预留。
  • rate=10r/s:平均速率。Nginx 实际按毫秒粒度执行,10r/s 相当于每 100 毫秒放行一个请求。
  • limit_req_status 429:被限流时返回的状态码,默认是 503,改成 429 更便于客户端识别。

二、burst 与 nodelay 的区别

仅设置 rate 不设 burst 时,超过速率的请求会被直接拒绝,短时间内的正常小突发也会误伤。

  • 设置 burst=20:允许最多 20 个请求“排队”超出速率。超过 rate 的请求不会立即拒绝,而是放进队列,按 rate 的节奏逐个处理。队列满了才拒绝。
  • 不加 nodelay:排队的请求会被延迟处理,用户感受到的是响应变慢,但最终都能成功。
  • 加上 nodelay:队列中的请求立即处理,不再人为延迟,但这些 burst 位置仍按 rate 的速度“恢复”,恢复之前再来的请求会被拒绝。

举例:rate=10r/s、burst=20、nodelay,一个客户端瞬间发来 30 个请求,前 21 个(1 个正常额度加 20 个 burst)立即处理,其余被拒绝,之后要等 burst 位置按每秒 10 个的速度恢复。

Nginx 1.15.7 起还支持 delay 参数:burst=20 delay=8 表示前 8 个超额请求不延迟,之后的排队延迟处理,介于两者之间,适合想兼顾体验与保护的场景。

三、limit_conn:限制并发连接

代码语言:nginx
复制
http {
    limit_conn_zone $binary_remote_addr zone=connperip:10m;

    server {
        location /download/ {
            limit_conn connperip 5;
            limit_rate 500k;
        }
    }
}

这里限制每个 IP 最多 5 个并发连接,并限制单连接速度,适合下载等长连接场景。limit_req 管“每秒多少次”,limit_conn 管“同时多少个”,两者互补。

四、常见坑

  1. 反向代理或负载均衡之后看到的都是同一个 IP:Nginx 前面有 CLB、CDN 时,$remote_addr 是上游的地址,会让所有用户共用一个限流额度。需要用 real_ip 模块还原真实客户端 IP,并且只信任来自可信代理的头:
代码语言:nginx
复制
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
  1. NAT 出口的多用户共用 IP:校园网、公司网络下,按 IP 限流可能误伤。可以对登录用户改用 token 或用户 ID 作为键(用 map 取请求头或 cookie 的值),或者适当放宽阈值。
  2. 白名单:内部监控、健康检查不应被限流。用 geo 与 map 为白名单 IP 生成空键,键为空的请求不会被限流:
代码语言:nginx
复制
geo $limit {
    default        1;
    10.0.0.0/8     0;
}
map $limit $limit_key {
    0 "";
    1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=perip:10m rate=10r/s;
  1. 只限了入口,没限昂贵接口:登录、短信发送、搜索这类接口应当单独设置更严格的限流。
  2. 多台 Nginx 时额度不共享:每个实例各自计数,总额度是各台之和。需要全局精确限流时,应在应用层或网关用集中式计数。

五、日志与验证

  1. 用 limit_req_log_level 控制拒绝日志的级别,错误日志里会出现 limiting requests, excess: ...。
  2. 用压测工具验证效果,例如 ab -n 100 -c 10 或 wrk,观察返回的 429 比例是否符合预期。
  3. 修改配置后先执行 nginx -t 检查语法,再 nginx -s reload。
  4. 上线前用观察模式:Nginx 1.17.1 起支持 limit_req_dry_run on;,只记录不拒绝,先看日志评估影响再正式启用。

小结

  • rate 控制平均速度,burst 允许短时突发,nodelay 决定排队请求是否延迟处理。
  • 限流键要选对,代理之后务必还原真实客户端 IP。
  • 关键接口单独限流,内部流量加白名单,上线前用 dry run 观察。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 背景
  • 一、limit_req:限制请求速率
  • 二、burst 与 nodelay 的区别
  • 三、limit_conn:限制并发连接
  • 四、常见坑
  • 五、日志与验证
  • 小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档