nginx对特定虚拟主机下行限速需将limit_rate置于对应server块内,单位为字节/秒(如500k=512000字节/秒),仅作用于响应体且按连接独立生效;配合limit_rate_after可实现前n字节不限速、之后恒定限速,二者必须共存才有效。

直接说结论:Nginx 只能对单个连接做静态限速,用 limit_rate + limit_rate_after 组合最实用;所谓“自动适配带宽”是伪需求,必须靠外部脚本轮询+重载才能模拟,且有抖动和中断风险。
limit_rate 怎么写才真正生效
它不是“限制总带宽”,而是每个 TCP 连接独立受限。用户开 3 个下载线程,总速就是 limit_rate × 3 —— 这点常被误判为“限速失效”。
- 单位是字节/秒,
500k= 500 × 1024 = 512000 字节/秒(≈ 488 KiB/s),不是 kbit/s;要限 2 Mbps 下行,得算成limit_rate 250k(2,000,000 ÷ 8 ÷ 1024 ≈ 244 → 向上取整) - 必须放在
location块里,比如只对 ZIP 文件限速:location ~ \.(zip|iso|tar\.gz)$ { limit_rate 300k; } - 设为
0表示不限速;不写则继承上级(默认为 0) - 若启用了
sendfile on,Linux 下可能首包突增、绕过限速,建议搭配tcp_nodelay on;或改用limit_rate_after缓解
limit_rate_after 怎么配合才像“智能”
它不能单独用,必须和 limit_rate 同时出现,作用是让前 N 字节“秒发”,之后才压速——这对视频头、安装包校验段很关键。
-
limit_rate_after 2m; limit_rate 100k;:前 2MB 不限速,之后恒定 ≈100KB/s - 只对 response body 生效,HTTP header 立即发送,不影响客户端解析速度
- 单位支持
m(兆字节)、k(千字节),100M是合法写法,但注意是字节不是 bit - 若文件小于
limit_rate_after值(比如设了5m但文件只有 2MB),则全程不限速
为什么你配了还是没限住
常见“失效”不是配置错,而是机制理解偏差或环境干扰:
- HTTP/2 多路复用下,
limit_rate仍按连接限速,但一个连接可承载多个请求,实际效果比 HTTP/1.1 更难感知 - gzip 开启后,
limit_rate限制的是压缩后的字节数(即真实网络流量),不是原始文件大小 - 客户端使用 range 请求(如断点续传)时,每个 range 是新子请求,
limit_rate_after对每个 range 单独计数 - error.log 默认不记录限速行为,也无对应 access_log 字段;验证得用
curl -o /dev/null -s -w '%{speed_download}\n'实测
想控总带宽?得换思路
limit_rate 天然不提供 IP 总速率聚合,真要防“单 IP 蹭满带宽”,必须组合其他模块:
- 先用
limit_conn_zone $binary_remote_addr zone=perip:10m;定义计数区 - 再在 location 里加
limit_conn perip 3;,限制同一 IP 最多 3 个并发连接 - 最后配
limit_rate 200k;,这样单 IP 最大下载速率为 3 × 200k ≈ 600KB/s - 注意:如果后端响应慢(如 PHP 卡住),这些连接会长期占用,新请求会被挂起甚至超时,现象是 503 或连接等待,不是速度变慢
真正容易被忽略的点是:限速只发生在 Nginx 向 client 发送数据阶段,不影响 upstream 处理、磁盘读取或 CPU 计算——如果你的瓶颈在后端,限速反而会让连接堆积,加重问题。











