无法直接用 limit_conn 按文件后缀限流,需组合 location 正则匹配、独立 bigfile zone、limit_rate、keepalive_timeout 5s、reset_timedout_connection 及 realip 处理,并通过 limit_conn_log_level warn 和日志分析实现可观测性。

直接用 limit_conn 无法按文件后缀限流——它只在 TCP 连接建立时计数,不解析请求路径或响应内容。要实现“针对大文件后缀的异常高频并发下载”做精准防护,必须组合使用 limit_conn + location 匹配 + 合理的 zone 定义,再辅以连接生命周期管理。
按文件后缀单独定义限流区域
不能把所有请求都塞进同一个 perip zone,否则图片、JS、API 全被连带限制。应专为大文件路径建 zone:
- 在
http{}块中新增:limit_conn_zone $binary_remote_addr zone=bigfile:10m; - 匹配常见大文件后缀(如
.zip、.iso、.dmg、.tar.gz):location ~* \.(zip|iso|dmg|tar\.gz|exe|mp4|avi)$ {<br> limit_conn bigfile 3;<br> limit_rate 512k;<br>} - 注意:正则 location 优先级高于普通
location /,确保它写在通用规则之前
避免空闲连接长期占坑
用户开多个标签页下载不同大文件,每个连接若保持 keepalive,会持续占用配额。必须收紧连接生命周期:
- 在该
location内加:keepalive_timeout 5s; - 配合全局设置:
reset_timedout_connection on;(防止半开连接滞留) - 这样即使用户发起 10 个下载,只要连接空闲超 5 秒就自动释放,真实并发数可控
区分真实客户端与代理/CDN
如果站点前有 CDN 或反向代理(如 Cloudflare、SLB),$binary_remote_addr 会变成代理 IP,导致误限。需还原真实 IP:
- 确认已配置
real_ip_header X-Forwarded-For;和set_real_ip_from可信段 - 将 zone 键改为:
limit_conn_zone $binary_remote_addr zone=bigfile:10m;→ 改为limit_conn_zone $realip_binary_remote_addr zone=bigfile:10m;
(需先定义map将$remote_addr映射为可信源 IP)
可观测与快速响应
光限流不够,得知道谁在刷、刷什么:
- 在
log_format中加入:$limit_key $limit(显示触发 zone 的键和当前连接数) - 加一行:
limit_conn_log_level warn;
让触发限流的请求写入 access log 而非 error log,方便 grep 分析 - 搭配简单脚本定时统计:
awk '$9==503 {print $1}' access.log | sort | uniq -c | sort -nr | head -10
快速定位异常 IP










