proxy_limit_rate本身不支持动态限速分流,仅支持基于连接的静态速率限制;需结合map模块动态映射限速值、upstream分组与split_clients或Lua实现按请求特征的动态限速与分流。

proxy_limit_rate 本身不支持动态限速分流,它只能对每个连接的响应流量做静态速率限制。要实现“动态限速分流”,需结合 Nginx 的变量、map 模块、limit_req 或第三方模块(如 nginx-module-vts、lua-nginx-module)协同完成,核心思路是:根据请求特征(如来源 IP、URL、Header)动态设置限速值,并配合 upstream 分组实现分流。
用 map + proxy_limit_rate 实现按条件动态限速
Nginx 的 map 指令可将请求变量映射为限速值,再通过 proxy_limit_rate 引用该变量。注意:proxy_limit_rate 只接受字面数值或变量,且变量必须在 rewrite 阶段已确定(map 在 server 块中预计算,安全可用)。
示例配置:
map $http_user_agent $limit_rate_val {
default 1024k;
~*curl 512k;
~*python-requests 256k;
~*mobile 128k;
}
<p>server {
location /api/ {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
proxy_limit_rate $limit_rate_val;
}
}</p>说明:
- map 中正则匹配 User-Agent,为不同客户端分配不同限速值;
- $limit_rate_val 是纯数值变量(单位 k/s),proxy_limit_rate 直接识别;
- 该方式是“限速”而非“分流”,所有请求仍打向同一 upstream。
结合 upstream 和 split_clients 实现真正分流
若需将流量按策略分发到不同后端集群(如高速通道 vs 降级通道),proxy_limit_rate 无法单独完成,需搭配 split_clients 或 lua 控制 upstream 选择,再对各组独立限速。
示例(按 IP 哈希分流 + 分组限速):
split_clients "$remote_addr" $upstream_group {
50% "high_speed";
* "low_bandwidth";
}
<p>upstream high_speed {
server 192.168.1.10:8080;
}</p><p>upstream low_bandwidth {
server 192.168.1.20:8080;
}</p><p>server {
location / {
set $backend_group $upstream_group;
proxy_pass <a href="https://www.php.cn/link/093d559928d57fc466488f5176506e29">https://www.php.cn/link/093d559928d57fc466488f5176506e29</a>;</p><pre class="brush:php;toolbar:false;"> proxy_limit_rate $backend_group = "high_speed" ? "2048k" : "512k";
# ⚠️ 注意:Nginx 原生不支持三元运算符,此处仅为示意逻辑
# 实际需用 map 映射 $upstream_group → 限速值
}
}
更稳妥做法:再加一层 map 将分组名转为限速值:
map $upstream_group $dynamic_rate {
"high_speed" 2048k;
"low_bandwidth" 512k;
}
<p>location / {
proxy_pass <a href="https://www.php.cn/link/db190973a7de5c5c876cba872133442f">https://www.php.cn/link/db190973a7de5c5c876cba872133442f</a>;
proxy_limit_rate $dynamic_rate;
}</p>进阶:用 Lua 动态决策(推荐用于复杂策略)
当限速逻辑依赖实时数据(如用户等级、API 调用频次、后端负载)时,OpenResty 的 lua-nginx-module 更灵活。可在 access_by_lua_block 中计算限速值并注入 header 或变量,再由 proxy_limit_rate 或自定义响应头控制行为。
关键点:
- 在 lua 中调用 redis 查询用户配额,生成 per-request 限速值;
- 用 ngx.var.xxx 设置 Nginx 变量,proxy_limit_rate 可引用;
- 也可直接在 lua 中调用 ngx.header["X-RateLimit-Limit"] 等标准限流头,供前端感知;
- 注意 lua 执行阶段:proxy_limit_rate 在 content 阶段生效,变量需在 rewrite 或 access 阶段赋值完成。
注意事项与常见误区
proxy_limit_rate 是 per-connection 限速,不是 per-request 或全局带宽限制:
- 一个长连接持续接收响应时,速率被限制;但多个并发连接会各自受限,总带宽可能叠加;
- 它只作用于 Nginx 向客户端发送响应体的速度,不影响后端处理或 proxy_buffering 行为;
- 若开启 proxy_buffering on(默认),Nginx 先收完后端响应再限速下发,此时限速体现为“客户端下载变慢”,而非后端减压;
- 真正降低后端压力,应配合 proxy_buffering off + proxy_limit_rate,让限速反压至后端(慎用,可能引发超时)。











