Nginx中需结合limit_req模块实现频次限制:先用limit_req_zone定义共享内存限流区(按IP或自定义变量),再在proxy_pass的location中启用limit_req,并可配合burst、nodelay、map及limit_req_status等增强控制与日志。

在 Nginx 中,仅靠 proxy_pass 本身无法实现频次限制;需结合 limit_req 模块对敏感接口做请求速率控制。核心思路是:先用 location 匹配敏感路径,再在该作用域内启用限流,并将流量转发给后端。
1. 定义限流区域(limit\_req\_zone)
限流必须基于一个共享内存区域,用于跨 worker 进程统计请求数。通常按客户端 IP 或自定义变量(如 token、API key)做区分:
- 按 IP 限流(最常用):
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=5r/s;
} - 若需按用户标识(如请求头中的
X-User-ID)限流,需先用map提取变量:
map $http_x_user_id $user_key {
default $http_x_user_id;
}
limit_req_zone $user_key zone=user_limit:10m rate=10r/m;
2. 在 proxy\_pass 的 location 中启用限流
匹配敏感接口路径(如 /api/v1/admin/ 或 /internal/),在内部启用 limit_req,再执行转发:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 基础写法(严格限流,超限直接 503):
location ^~ /api/v1/admin/ {
limit_req zone=api_limit burst=10 nodelay;
proxy_pass http://backend;
} -
burst允许突发请求缓冲,nodelay表示不延迟处理(立即响应或拒绝),适合防刷;若希望平滑排队,去掉nodelay,Nginx 会按速率匀速放行缓冲队列中的请求。
3. 针对特定方法或条件细化控制
敏感接口常只对 POST/DELETE 等高危方法限流,可配合 if + limit_req(注意:if 在 location 中可用,但不宜嵌套复杂逻辑):
- 仅对 POST 请求限流:
location ^~ /api/v1/transfer/ {
if ($request_method = POST) {
limit_req zone=pay_limit burst=3;
}
proxy_pass http://payment_svc;
} - 更推荐方式:用
map构建动态键,例如:
map "$request_method:$uri" $req_key {
default "";
"POST:/api/v1/login" "login";
"POST:/api/v1/withdraw" "withdraw";
}
limit_req_zone $req_key zone=action_limit:10m rate=2r/s;
再在 location 中引用limit_req zone=action_limit;
4. 增强防护:结合返回状态与日志识别异常
限流触发时默认返回 503,可通过 limit_req_status 自定义状态码(如 429),便于前端识别;同时记录被限流的请求,辅助分析:
- limit_req zone=api_limit burst=5;
limit_req_status 429;
log_format limit_log '$remote_addr - $remote_user [$time_local] "
$request" $status $body_bytes_sent $request_time
"$http_referer" "$http_user_agent" req_count=$limit;
access_log /var/log/nginx/limit_api.log limit_log; - 注意:
$limit变量需开启limit_req_log_level warn;才能生效,且仅在拒绝请求时有值。

















