单接口精准限流需在location块中用=精确匹配路径并配置limit_req,配合http块中以$uri定义的limit_req_zone实现按接口分桶限流,burst与nodelay控制突发处理,返回429并记录$limit便于排查。

直接在目标 location 块中配置 limit_req,配合 limit_req_zone 定义,就能实现单接口精准限流。关键不是加在哪里,而是怎么匹配、怎么定义、怎么控制行为。
用精确匹配锁定单一接口
别用前缀匹配(比如 location /api/),否则 /api/v1/order 和 /api/v1/user 全被框住。要用 = 实现完全相等匹配:
location = /api/v1/order {-
limit_req zone=order_limit burst=8 nodelay; -
proxy_pass http://backend; }
这样只有 GET /api/v1/order HTTP/1.1 这种完整路径才触发限流,其他路径不受影响。
按接口路径定义限流区域
限流要“按接口分桶”,不能只按 IP。在 http 块里这样写:
limit_req_zone $uri zone=order_limit:10m rate=3r/s;
$uri 只取路径部分(不含 query string),所以 /api/v1/order?id=123 和 /api/v1/order?token=abc 都算同一个接口;rate=3r/s 表示该接口每秒最多放行 3 个请求;10m 内存足够存几万个不同 URI 的状态,够用。
控制突发和响应方式
burst 和 nodelay 组合决定流量怎么“削峰”:
-
burst=8 nodelay:允许最多 8 个请求立刻通过,超了就直接返回 429 -
burst=8(不加nodelay):超出速率的请求会排队,按每秒 3 个匀速放行,延迟升高但更平滑 -
burst=0或省略burst:严格卡死速率,连瞬时抖动都不放——适合核心下单、支付类接口
返回码和日志要能定位问题
默认返回 503 不利于前端识别,加上这句:
limit_req_status 429;
再在 log_format 中加入 $limit 变量:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $limit';
日志里就能看到哪条请求命中了 order_limit 区域,方便排查是否误配或被刷。











