Nginx防多线程下载需三层控制:一限并发连接数(如每IP最多2连),二控单连速率(如前3MB不限速、之后800KB/s),三限请求频次(如3r/s+burst=6);并注意HTTP/2、sendfile及Range请求的特殊影响。

单个客户端开多个线程下载,本质是绕过单连接限速的最常见方式。Nginx 本身无法聚合同一 IP 的所有连接来统一分配带宽,所以必须用“连接数 + 单连速率 + 请求频次”三层控制,才能真正防住。
一、先掐死并发连接数
每个下载线程通常对应一个独立 TCP 连接,限制连接数是最直接的拦截手段:
- 在 http 块中定义共享内存区:
limit_conn_zone $binary_remote_addr zone=perip:10m;
($binary_remote_addr比$remote_addr更省内存,10MB 可存约 16 万个 IPv4 客户端) - 在目标下载路径的 location 中启用限制,例如只对
/download/或/chunks/生效:location ^~ /download/ {<br> limit_conn perip 2;<br>}
表示每个真实客户端最多维持 2 个并发连接,第 3 个直接返回 503 - 若后端有 CDN 或四层 LB,需配合
set_real_ip_from和$http_x_forwarded_for,否则所有流量会被识别为同一个源 IP
二、再压住单连接传输速率
即使只允许 2 个连接,每个连接仍可能高速拖大文件。用 limit_rate 控制单连接下行速度:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 必须和
limit_rate_after成对使用,否则无法实现“开头快、后面稳”的合理体验:limit_rate_after 3m;<br>limit_rate 800k;
含义:前 3MB 立即发送(保障视频头、校验段秒开),之后恒定 ≈800KB/s(即约 6.4Mbps) - 单位是字节/秒:
800k = 800 × 1024 = 819200 字节/秒;想限 2Mbps,应写limit_rate 250k(2,000,000 ÷ 8 ÷ 1024 ≈ 244 → 向上取整) - 该限速作用于 Nginx → client 的响应体,对
proxy_pass流量同样生效;但注意:它不控总带宽,只控每个连接
三、叠加请求频次限制防重试与预取
恶意客户端可能快速建连、发完就断,反复触发。仅靠连接数不够,需补漏:
- 定义请求限速区域:
limit_req_zone $binary_remote_addr zone=dl_rate:10m rate=3r/s; - 在同个 location 中应用:
limit_req zone=dl_rate burst=6 nodelay;
表示每秒最多 3 个新请求,允许最多 6 个瞬时请求(如合法重试或并行预取),超出立即拒绝(503),不排队 - 注意:
burst是缓冲池大小,nodelay表示不延迟处理,适合分块服务场景
四、关键提醒:别踩这些坑
配置写对了,不代表效果到位。以下三点最容易被忽略:
- HTTP/2 多路复用下,一个连接可承载多个下载请求,
limit_conn仍按连接计数,但实际并发逻辑更复杂;建议在server块中加http2_max_requests 100;防止单连接长期霸占 - 开启
sendfile on时,首包可能突增绕过limit_rate;建议搭配tcp_nodelay on;或改用limit_rate_after缓解 - Range 请求(断点续传)每个 range 视为独立子请求,
limit_rate_after对每个 range 单独计数;若文件只有 1MB,而设了limit_rate_after 2m,则全程不限速










