可通过Nginx的limit_req模块结合map指令为不同合作伙伴IP设置独立限速策略:先用map将IP映射为partner_a等标识,再按标识定义对应limit_req_zone,最后在location中用limit_req zone=$partner_key动态匹配限速区。

可以通过 Nginx 的 limit_req 模块结合 map 指令,为不同合作伙伴 IP 设置独立的请求速率限制策略,实现差异化静态流量整形。
基于 IP 分组定义差异化限速规则
核心思路是先用 map 将合作方 IP 映射到不同的限速等级标识(如 partner_a、partner_b),再在 limit_req_zone 中按该标识划分独立的共享内存区域,从而隔离各合作方的令牌桶状态。
- 在
http块中定义 IP 到限速 key 的映射:
map $remote_addr $partner_key {
default "default";
192.168.10.5 "partner_a";
203.0.113.22 "partner_b";
2001:db8::1 "partner_a"; # 支持 IPv6
}
- 为每个 key 定义独立的限速 zone(注意:key 必须唯一,zone 名称需与 key 对应):
limit_req_zone $partner_key zone=partner_a:10m rate=10r/s;
limit_req_zone $partner_key zone=partner_b:10m rate=5r/s;
limit_req_zone $partner_key zone=default:10m rate=1r/s;
在 server 或 location 中动态选择限速策略
利用 limit_req 的 zone 参数配合变量,根据 $partner_key 值自动匹配对应 zone。Nginx 会按变量实际值查找已声明的 zone:
- 在目标
location内添加如下指令:
limit_req zone=$partner_key burst=20 nodelay;
⚠️ 注意:zone= 后必须接变量(如 $partner_key),且该变量值必须与某个 limit_req_zone 声明中的 zone 名完全一致;否则会因 zone 未定义而报错或退化为默认行为。
补充控制细节与常见优化项
-
支持 CIDR 匹配:若合作方提供的是 IP 段,可用
geo指令替代map,更高效地处理网段(例如192.168.10.0/24); -
避免 key 冲突:确保
map输出的 key 命名不重复,且与所有limit_req_zone的 zone 名严格一致; -
日志标记便于排查:可在 log_format 中加入
$partner_key,快速识别请求归属及是否命中限速; -
burst 和 nodelay 的取舍:对敏感接口建议设较小 burst(如 5~10),并去掉
nodelay以平滑突发;对容忍延迟的合作方可开启nodelay提升瞬时吞吐。
验证与调试建议
上线前务必通过 nginx -t 校验配置语法,并用 curl -I 多次请求观察响应头中的 X-RateLimit-Limit(需配合第三方模块或自定义 header)或直接查看 error.log 中的限速拒绝记录(含 limiting requests 字样)。可临时开启 limit_req_log_level warn; 提高日志粒度。










