X-Accel-Limit-Rate 是由后端通过响应头传递给 Nginx 的动态限速指令(字节/秒),仅对 proxy_pass 等代理生效;需用 map 基于 $upstream_response_time 字符串匹配耗时区间映射限速值,并配合 add_header ... always 和 proxy_buffering off 在 location 中注入,确保响应头发送前生效。

在 Nginx 中,X-Accel-Limit-Rate 是一个由后端(如应用服务器)通过响应头传递给 Nginx 的指令,用于动态控制向客户端发送响应体时的速率(单位:字节/秒)。但注意:Nginx 本身不原生支持基于请求耗时(如 upstream_response_time)动态设置该头 —— 因为 X-Accel-Limit-Rate 是响应阶段生效的响应头,而耗时指标(如 $upstream_response_time)只能在日志或变量中使用,无法直接在响应头中参与条件计算。
不过,可通过 map + add_header(配合 proxy_pass 和 fastcgi_pass 等代理模块)实现“近似动态限速”:即在请求结束前,根据上游响应耗时预估并注入限速值。关键在于:限速逻辑必须在响应头发送前完成,且依赖于已知的耗时变量。以下是可行方案:
前提:启用响应头透传与变量支持
确保 Nginx 编译时启用了 --with-http_realip_module(非必需)和标准 proxy/fastcgi 模块;同时确认后端未覆盖或清除你将要注入的 X-Accel-Limit-Rate 头。
- 若用
proxy_pass,需开启proxy_buffering off或合理配置缓冲,避免响应体提前发送导致限速失效 -
X-Accel-Limit-Rate仅对proxy_pass/fastcgi_pass/scgi_pass/uwsgi_pass生效,对静态文件无效 - 该头值为整数(字节/秒),如
102400表示 100KB/s;设为0表示禁用限速
用 map 基于 upstream_response_time 映射限速值
map 指令可在请求处理早期(rewrite 阶段)将变量映射为新变量,但 $upstream_response_time 是在 upstream 完成后才填充的 —— 所以它不能直接用于 map 做实时判断。正确做法是:在 location 中用 add_header + always,结合内置变量(如 $upstream_response_time)进行简单运算(Nginx 1.13.2+ 支持基本算术):
map $upstream_response_time $limit_rate_val {
~^[0-9]+\.([0-9]{1,3})$ $1; # 提取小数点后三位(不推荐,精度低)
default 0;
}
但上述方式不可靠。更实用的是:用 map 将耗时区间映射为预设限速档位:
$upstream_response_time
-
add_header默认不继承,需在每个需要限速的location中显式写入 -
proxy_buffering off是关键:若开启缓冲,响应体可能已开始发送,此时添加限速头无效 -
$upstream_response_time在失败请求(如超时、502)中为空或为“-”,map会走 default 分支;建议搭配proxy_next_upstream和健康检查提升稳定性 - 若需更高精度(如按毫秒级线性限速),需改用 Lua(OpenResty)或外部服务做决策,Nginx 原生命令能力有限
- 该方案限速作用于 Nginx → Client 链路,不影响 upstream → Nginx 的传输速度
不复杂但容易忽略:限速值必须是整数,且仅对代理响应体生效;务必验证 add_header ... always 是否真实出现在响应头中(用 curl -I 测试),并确认后端未覆盖该头。










