limit_conn是保障下载带宽不被单客户端耗尽最轻量可靠的方式,基于TCP连接建立时计数,需在http块定义zone(如$binary_remote_addr zone=download_ip:10m),再在location中配置limit_conn download_ip 3,并配合limit_rate、429状态码及真实IP还原提升实用性。

直接用 limit_conn 限制并发下载连接数,是保障负载均衡集群带宽不被单个客户端耗尽最轻量、最可靠的方式。它在 TCP 连接建立时就计数,不解析请求内容,不依赖 HTTP 协议,天然适配各种下载场景(如大文件、断点续传、HTTP/2 多路复用),且开销极低。
先建连接计数“账本”:定义 limit_conn_zone
必须在 http{} 块中完成,这是所有限流的前提:
- 用
$binary_remote_addr作为键,比$remote_addr更省内存(每个 IP 约 64 字节),10MB 内存可容纳约 16 万个独立客户端状态 - 示例:
limit_conn_zone $binary_remote_addr zone=download_ip:10m;—— 为下载类流量单独建一个 zone,避免和普通 API 连接混用 - 不建议用
$uri或$args作 key,键太多会快速撑爆共享内存
在下载入口处启用连接限制
把限流规则加在专门处理下载的 location 块里,精准控制,不影响其他业务:
- 例如:
location /downloads/ { limit_conn download_ip 3; }—— 每个 IP 最多维持 3 个并发下载连接 - 若后端是集群,且需全局总连接数兜底,可再加一层:
limit_conn_zone $server_name zone=cluster_total:5m;+limit_conn cluster_total 500; - 注意:HTTP/2 的一个连接无论含多少 stream,只算 1 个;keepalive 空闲连接也持续占配额,建议搭配
keepalive_timeout 15;
配合限速与可观测性增强实用性
单纯限连接数够用,但加几行就能更稳、更好查:
-
limit_rate 512k;—— 对每个被允许的下载连接限速,防止单连接吃满带宽;注意这不是按 IP 限速,而是按连接限速 -
limit_conn_status 429;—— 返回 429 Too Many Requests,语义比默认 503 更准确,便于前端识别重试逻辑 -
limit_conn_log_level error;—— 把触发限流的日志级别提到 error,避免 warn 刷屏掩盖真正问题 - 在
log_format中加入$limit和$limit_key,access log 里就能看到谁被限、因哪个 zone 被限
特别注意真实 IP 和 CDN 场景
负载均衡集群前常有 SLB、CDN 或反向代理,否则 $binary_remote_addr 拿到的是代理 IP,失去限流意义:
- 配置
set_real_ip_from指定可信代理网段,再用real_ip_header X-Forwarded-For;或X-Real-IP - 验证是否生效:临时加一行
add_header X-Real-IP $binary_remote_addr;,curl 查看响应头 - 若使用阿里云 SLB、腾讯云 CLB 等,需确认其透传真实 IP 的 header 名称,并同步调整 real_ip_header

















