通过map指令基于$uri生成$limit_key实现路径分组限流,为/static/、/images/、/api/v1/login、/api/等路径分别配置static、login、api等独立zone,再在对应location中调用limit_req绑定zone并设置burst/nodelay参数,确保差异化QPS控制。

使用 limit_req 对不同 API 路径实现差异化 QPS 限流,核心在于结合 limit_req_zone 的变量定义与 location 块的精准匹配,让每个路径(或路径组)使用独立的限流规则。静态资源(如 /static/、/images/)通常可设更高 QPS,而敏感 API(如 /api/v1/login)则需更严格限制。
定义多个限流区域(zone)
每个 zone 对应一类路径的限流策略,通过 $uri、$request_uri 或自定义变量(如 $limit_key)区分流量来源:
- 用
$uri可按完整路径限流(适合精确控制单个接口) - 用正则提取前缀(如
~^/api/)配合map指令生成统一限流键,更适合分组管理 - 避免直接对
$binary_remote_addr全局限流,否则无法体现“路径差异化”
示例:
map $uri $limit_key {
~^/static/ static_zone;
~^/images/ static_zone;
~^/api/v1/login login_zone;
~^/api/ api_zone;
default default_zone;
}
limit_req_zone $limit_key zone=static:10m rate=100r/s;
limit_req_zone $limit_key zone=login:10m rate=5r/s;
limit_req_zone $limit_key zone=api:10m rate=20r/s;
limit_req_zone $limit_key zone=default:10m rate=10r/s;
在 location 中绑定对应限流规则
根据路径特征,在 location 块中调用 limit_req,并指定 zone 名称和可选参数(如 burst、nodelay):
-
/static/和/images/共享static_zone,允许突发 200 请求且不延迟 -
/api/v1/login单独走login_zone,严格限速,不设 burst 防暴力尝试 - 其他 API 路径走
api_zone,兼顾可用性与防护
配置片段:
location ^~ /static/ {
limit_req zone=static burst=200 nodelay;
alias /var/www/static/;
}
location ^~ /images/ {
limit_req zone=static burst=200 nodelay;
alias /var/www/images/;
}
location = /api/v1/login {
limit_req zone=login;
proxy_pass http://backend;
}
location ^~ /api/ {
limit_req zone=api burst=40;
proxy_pass http://backend;
}
注意 key 的唯一性与粒度控制
限流是否真正“按路径差异化”,取决于 $limit_key 的取值逻辑:
- 若 map 中将所有
/api/开头路径映射为同一 key,则它们共享 QPS,不是完全独立限流 - 如需每个 API 路径单独限流,可改用
$uri作为 key,但需确保 zone 内存足够(大量路径会消耗更多共享内存) - 对带查询参数的请求,
$uri不含参数,$request_uri含参数——通常用$uri更合理,避免相同接口因参数不同被误判为多条流
验证与调试技巧
上线前建议通过日志和测试确认行为符合预期:
- 开启
limit_req_log_level warn,在 error log 中查看被限流的请求详情 - 用
ab或wrk对不同路径并发压测,观察响应状态码(429 表示触发限流) - 检查
nginx -t确保 map 和 limit_req_zone 无语法错误,reload 后用nginx -s reload
不复杂但容易忽略:限流生效前提是请求实际匹配到设置了 limit_req 的 location 块,注意 location 匹配优先级(= > ^~ > 正则),避免规则被更宽泛的块覆盖。

















