可通过Nginx的limit_req模块结合多个limit_req_zone和map指令,为不同API路径或请求方法设置差异化QPS限流策略;需在http块定义zone、用location绑定、以map构造动态key实现细粒度控制。

可以通过 Nginx 的 limit_req 模块结合多个 limit_req_zone 定义,为不同 API 路径设置独立的 QPS 限流策略。
定义多个限流区域(zone)
每个 zone 对应一个路径或路径组,使用 $request_uri、$host 或自定义变量(如通过 map 提取路径前缀)作为 key:
- 对
/api/v1/users单独限流:用map $request_uri $user_zone_key匹配该路径,生成唯一 key - 对
/api/v1/orders设置更宽松策略:另起一个 zone,key 可设为"orders"或匹配正则提取 - 避免全站共用一个 zone,否则无法实现“差异化”——不同路径必须对应不同 zone 名称
在 location 中按路径绑定限流规则
利用 location 的精确匹配或前缀匹配,将对应 zone 应用到具体路由:
location = /api/v1/users { limit_req zone=users burst=5 nodelay; }location ^~ /api/v1/orders { limit_req zone=orders burst=20 delay=10; }- 注意:多个
limit_req指令不能在同一 location 中叠加;如需组合条件(如按用户 ID + 路径),需在 map 中构造复合 key
用 map 构造动态限流 key 实现细粒度控制
当需要按路径层级(如 /api/v1/xxx)或参数特征(如是否含 ?export=1)分流时,map 是关键:
- 示例:区分读写接口:
map $request_method:$request_uri $req_key { ~^(GET|HEAD):/api/v1/.*$ "read"; ~^(POST|PUT|DELETE):/api/v1/.*$ "write"; } - 再基于
$req_key定义 zone:limit_req_zone $req_key zone=api_rw:10m rate=10r/s; - 这样 GET 类请求走 10 QPS,POST 类可另设 5 QPS zone,真正实现路径+方法双重差异化
验证与调试要点
限流生效依赖配置加载顺序和变量计算时机,常见问题有:
- 返回
503 Service Temporarily Unavailable表示触发限流;返回503但日志无记录?检查 zone 是否在http块顶层定义,而非嵌套在 server 内 - burst 参数允许突发请求排队,nodelay 则直接拒绝超限请求;测试时用
ab -n 100 -c 20观察响应分布 - 若某路径未被限流,用
error_log /path/to/log notice;开启 notice 级日志,查看是否因 key 为空(如 map 未命中)导致 zone 未生效

















