limit_conn保护高能耗路径需按ip+location精准限流:先在http块定义zone(如conn_per_ip:1m),再在目标location(如/api/v1/heavy-task)中配置limit_conn conn_per_ip 3,并注意代理环境下用real_ip_module还原真实ip。

用 limit_conn 保护高能耗路径,核心是“按 IP + 按 location 精准限流”,避免全局压垮后端或触发雪崩。它不直接限制请求数(那是 limit_req),而是控制每个 IP 同时打开的连接数——这对长连接、慢接口、文件下载、WebSocket 升级等场景特别有效。
1. 先定义 connection zone(必须在 http 块)
zone 是内存共享区,用来记录每个 IP 的当前并发连接数。名称和大小要合理:
-
名称唯一:比如
conn_per_ip,后续在 location 中引用 -
大小够用:1m 约存 1.6 万个 IP 记录;若预估峰值 IP 数 ≤5000,设
1m足够 -
不能放在 server 或 location 内:必须在
http{...}顶层定义
http {
limit_conn_zone $binary_remote_addr zone=conn_per_ip:1m;
}
2. 在目标 location 中启用 limit_conn
只对高能耗路径(如 /api/report、/download/bigfile)启用,不影响其他静态资源或轻量接口:
-
用
$binary_remote_addr:比$remote_addr更省内存,且不受 X-Forwarded-For 伪造影响(Nginx 默认信任真实客户端地址) - 并发数设保守值:例如 3~5,足够应对正常用户多标签页/重试,但拦住爬虫或误调用
- 配合 error_page 处理被拒绝连接:返回 503 或自定义提示,避免客户端无限重连
location ^~ /api/v1/heavy-task {
limit_conn conn_per_ip 3;
limit_conn_status 503;
proxy_pass http://backend;
proxy_set_header Host $host;
}
3. 注意 real-ip 和代理链的影响
如果 Nginx 前还有 CDN 或负载均衡(如 SLB、ALB),$binary_remote_addr 默认是上一跳地址,不是真实用户 IP:
- 需先配置
set_real_ip_from和real_ip_header,让 Nginx 正确识别真实客户端 IP - 否则所有请求会被当成同一个 IP 限流,或完全失效
- 验证方式:
log_format加入$remote_addr和$binary_remote_addr对比日志
4. 配合其他机制效果更稳
limit_conn 是连接层防御,建议叠加使用:
-
后端加超时与熔断:Nginx 设置
proxy_read_timeout 30,防慢后端拖死连接池 -
区分动静态路径:对 /static/、/img/ 等不启用
limit_conn,避免影响页面加载 -
监控 zone 使用率:通过
stub_status或nginx-module-vts观察conn_per_ip的饱和度和拒绝数











