limit_rate + limit_rate_after 是唯一开箱可用的单IP带宽限制方案,但按连接限速而非IP总带宽,多连接可绕过;Nginx无IP级带宽聚合能力,二者须同作用域配置,限速单位为字节/秒,实测有±15%浮动。

直接说结论:limit_rate + limit_rate_after 是唯一开箱可用的单IP带宽限制方案,但它是按连接限速,不是按IP总带宽限速——客户端开多个连接就能绕过。
为什么不能真正“按IP限带宽”
Nginx 没有模块能聚合同一 IP 的所有连接并统一分配带宽。它只在每个 TCP 连接建立后,独立应用 limit_rate。这意味着:
- 一个 IP 开 4 个下载线程 → 总速 ≈ 4 ×
limit_rate -
limit_conn_zone管连接数,limit_rate管单连接流速,二者不联动 - 没有
limit_bandwidth_per_ip这种指令,所有“IP级带宽限速”都是伪需求或需外部调度
limit_rate 和 limit_rate_after 必须成对写
单独写 limit_rate 200k 会生效,但无法实现“先快后慢”的体验;加了 limit_rate_after 才能模拟真实下载场景:
-
limit_rate_after 5m表示前 5MB 不限速(header + 视频头/安装包校验段秒开) -
limit_rate 200k从第 5MB+ 开始生效,单位是字节/秒(不是 bit) - 必须同时出现在同一作用域(
server或location),否则limit_rate_after被忽略 - 对
proxy_pass流量也生效,限的是 Nginx → client 的下行,不是 upstream → Nginx 的上行
单位换算和实测浮动要心里有数
你写的数字 ≠ 实际网卡速率,因为受系统 socket buffer、TCP window、客户端接收能力影响:
- 想限 1Mbps 下行 → 计算:1,000,000 ÷ 8 = 125,000 字节/秒 → 向上取整写
limit_rate 125k -
500k= 500 × 1024 = 512,000 字节/秒 ≈ 498 KiB/s,不是 500 kbit/s - 实测速率通常有 ±15% 浮动,别拿 iPerf 对标;压测时用
curl -r 0-10485760 http://x/x.zip > /dev/null更准 - CDN 场景下,
$binary_remote_addr拿到的是 CDN 节点 IP,limit_rate仍按该 IP 生效,无法穿透
真正难处理的从来不是配置语法,而是并发连接绕过限速这个事实——它没法被 limit_conn 拦住,因为那是另一个维度的事。要么接受“单连限速”,要么用 iptables + tc 做系统层整形,但 reload 会中断连接,且无法 per-HTTP-session 精细控制。


















