可在Nginx中用map指令按请求方法映射不同limit_req_zone实现差异化限流:先在http块定义map将GET/POST等映射到对应zone名,再分别配置各zone速率(如GET 100r/s、POST 20r/s),最后在location中通过limit_req zone=$method_zone动态启用。

可以在 Nginx 中通过 map 指令将请求方法($request_method)映射为不同的限流 zone 名,再配合多个 limit_req_zone 定义,实现对不同 HTTP 方法(如 GET、POST、PUT、DELETE)施加差异化的 QPS 限制。
用 map 区分请求方法并绑定限流 zone
在 http 块中定义 map,把常见方法映射到对应 zone 名:
map $request_method $method_zone {
GET "get_zone";
POST "post_zone";
PUT "put_zone";
DELETE "delete_zone";
default "default_zone";
}
注意:$request_method 是大小写敏感的纯字符串(如 GET),无需正则;若需兼容大小写混合,可用 map_insensitive(需 OpenResty 或较新 Nginx 版本),否则建议统一规范客户端行为。
定义各方法专属的 limit_req_zone
每个 zone 独立配置速率,key 可保持一致(如按 IP 限流):
limit_req_zone $binary_remote_addr zone=get_zone:10m rate=100r/s; limit_req_zone $binary_remote_addr zone=post_zone:10m rate=20r/s; limit_req_zone $binary_remote_addr zone=put_zone:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=delete_zone:10m rate=5r/s; limit_req_zone $binary_remote_addr zone=default_zone:10m rate=1r/s;
例如:GET 允许高频查询(100 QPS),而 POST/PUT/DELETE 因涉及写操作更严格,逐级收紧。
在 location 中启用动态限流
直接引用 $method_zone 变量即可自动匹配已定义的 zone:
location /api/ {
limit_req zone=$method_zone burst=10 nodelay;
proxy_pass http://backend;
}
-
burst=10统一设置缓冲容量,适用于所有方法;也可用另一个map单独映射$burst_size实现 per-method burst 差异化 - 若某方法(如
OPTIONS)完全不限流,可在 map 中映射为未定义 zone 名(如"unlimited"),并在limit_req后加dry_run——但更稳妥的做法是单独写一个不带limit_req的location = /health或用if ($request_method = OPTIONS) { ... }跳过
验证与注意事项
检查是否生效可结合日志和状态码:
- 发送高频 POST 请求,观察是否返回
503 Service Temporarily Unavailable - 查看 error log 中
limiting requests行,确认命中的是post_zone而非其他 zone - 确保
map块位于http级且在所有limit_req_zone之后,否则变量未定义会报错 - 不建议在同一个 location 内叠加多个
limit_req指令(如分别写limit_req zone=get_zone和limit_req zone=post_zone),Nginx 仅执行最后一条


















