核心是分层控制:在nginx入口限流后分发至upstream集群,通过$binary_remote_addr等key精准限流,配合zone定义、burst/nodelay调优及白名单与json错误响应优化,实现前置、可扩展的边缘接口防护。

用 limit_req 配合 upstream 构建边缘接口限流防线,核心是分层控制:在请求入口(Nginx)完成速率限制,再把合规流量分发到后端服务集群。这不是简单叠加,而是让限流逻辑前置、精准、可扩展。
明确限流粒度与 key 设计
限流效果取决于你用什么做 key。对边缘接口,常见选择有:
-
$binary_remote_addr:最常用,按客户端真实 IP 限流。注意使用二进制形式节省内存,IPv4 固定占 4 字节;若走 CDN 或代理,需配合
X-Forwarded-For和real_ip模块还原真实源 IP - $http_x_user_id:按业务用户 ID 限流(需客户端透传),适合登录态强管控场景,避免同一 IP 下多账号互相干扰
-
$uri 或 $host$uri:按接口路径限流,比如只对
/api/v1/pay做严控,其他接口宽松
不建议直接用 $remote_addr,因字符串长度不固定,内存开销大且哈希效率低。
定义共享内存 zone 并绑定 upstream
在 http 块中定义限流区域,大小按预估并发 IP 数预留:
- 10MB zone 约支持 16 万 IPv4 地址状态(64 字节/状态 × ~160,000)
- rate 值参考后端单节点 QPS 承载能力 × 节点数 ÷ 安全系数(如 0.7)。例如 3 台后端,每台稳态处理 200 QPS,则设
rate=420r/s - 示例:
limit_req_zone $binary_remote_addr zone=edge_api:10m rate=420r/s;
upstream 本身不参与限流计算,但它是流量出口。确保 upstream 配置合理(如 ip_hash 或 least_conn)能承接限流后的均匀流量,避免某节点过载。
在 location 中精准启用并调优 burst/nodelay
把限流策略落在具体接口路径上,而非全局 server:
-
limit_req zone=edge_api burst=200 nodelay;表示允许最多 200 个请求瞬时涌入,并立即处理(不排队),超出部分直接返回 503 -
burst不是越大越好——它代表缓冲队列长度,过大可能掩盖后端延迟问题;一般设为平均秒级流量的 1.5~2 倍较稳妥 - 若需平滑削峰(如防止突发打满后端连接池),可去掉
nodelay,让超额请求排队等待,但需注意客户端超时设置是否匹配
示例配置片段:
location /api/ {limit_req zone=edge_api burst=200 nodelay;
proxy_pass http://my_upstream;
proxy_set_header X-Real-IP $remote_addr;
}
排除白名单与错误响应优化
运维、监控、内部系统 IP 需豁免限流:
- 用
geo+map构建白名单映射,使白名单 IP 的限流 key 为空(即不触发限制) - 将限流拒绝响应统一为 JSON 格式,便于前端识别处理,例如:
error_page 503 /limit_exceeded.json;
location = /limit_exceeded.json {
default_type application/json;
return 503 '{"code":429,"msg":"Too Many Requests"}';
}
这样既保障核心链路不被误伤,又提升错误反馈的可观测性与用户体验。











