Nginx可通过map指令结合$sent_http_content_type或$uri动态设置limit_rate限速值,实现按文件类型(如.zip、.pdf、.mp4)差异化限速,并支持limit_rate_after跳过初始部分及VIP用户提额等进阶策略。

nginx 的 limit_rate 指令本身不支持按文件类型或路径动态设置不同限速值,它只能在 location、server 或 http 级别静态配置一个固定速率。但通过合理组合 location 匹配、map 指令和变量,完全可以实现“针对不同静态资源(如 .zip、.pdf、.mp4)应用不同下载限速”的实战效果。
用 map 构建资源类型到限速值的映射
核心思路是:先根据请求 URI 后缀识别资源类型,再映射为对应的限速数值(单位 byte/s),最后将该变量传给 limit_rate。
在 http 块中定义:
map $sent_http_content_type $limit_rate_value {
default 0; # 默认不限速
~application/zip 512k; # ZIP 文件限速 512KB/s
~application/pdf 256k; # PDF 文件限速 256KB/s
~video/ 1m; # 所有视频(MP4、AVI等)限速 1MB/s
~application/octet-stream 128k; # 通用二进制流(兜底常见大文件)
}注意:$sent_http_content_type 是响应头中的 MIME 类型,比仅匹配后缀更准确(尤其当后缀被隐藏或误配时)。若需严格按后缀控制,也可改用 $request_uri 或 $uri,例如:
map $uri $limit_rate_value {
~\.(zip|rar|7z)$ 512k;
~\.(pdf|epub)$ 256k;
~\.(mp4|avi|mkv)$ 1m;
default 0;
}在 location 中启用动态限速
确保你的静态资源由 nginx 直接提供(非 proxy_pass),并在对应 location 块中引用变量:
location /static/ {
alias /var/www/static/;
expires 1h;
add_header X-Rate-Limit-Used $limit_rate_value; # 方便调试
<pre class="brush:php;toolbar:false;">limit_rate $limit_rate_value;
limit_rate_after 10m; # 前 10MB 不限速,之后开始限速(可选)}
关键点:
-
limit_rate支持变量,但变量必须在响应头已生成后才可读取(因此推荐基于$sent_http_content_type) -
limit_rate_after可提升用户体验:允许用户快速加载文件开头(如 PDF 首页、视频关键帧),后续再限速 - 避免在 root 或 autoindex location 中直接使用未定义变量,否则会报错;务必保证
map已声明且变量有默认值
验证与调试技巧
实际生效前建议逐项验证:
- 用
curl -I查看响应头是否含X-Rate-Limit-Used,确认变量取值正确 - 用
curl -r 0-20971520 http://example.com/static/test.zip --output /dev/null测试大文件下载速度(-r 模拟范围请求,避免缓存干扰) - 检查 error_log 中是否有
limit_rate: invalid value类错误,通常因变量为空或格式非法导致 - 若限速未生效,确认 location 是否真正命中(可用
log_format加入$limit_rate_value和$sent_http_content_type日志字段排查)
进阶:结合 $remote_addr 实现用户级差异化限速
如需对 VIP 用户放宽限制,可叠加 IP 判断:
map $remote_addr $is_vip {
192.168.1.100 1;
2001:db8::1 1;
default 0;
}
<p>map $sent_http_content_type $base_rate {
~application/zip 512k;
~application/pdf 256k;
default 0;
}</p><p>map "$is_vip:$base_rate" $limit_rate_value {
"1:512k" 2m; # VIP 下载 ZIP 提速至 2MB/s
"1:256k" 1m; # VIP 下载 PDF 提速至 1MB/s
"0:512k" 512k;
"0:256k" 256k;
default 0;
}</p>这种嵌套 map 写法灵活,但需注意变量拼接格式一致(冒号分隔)、顺序匹配优先级,以及避免空格引发解析失败。










