Nginx通过limit_req模块配合漏桶算法实现请求速率平滑控制,需定义共享限流区、设置burst缓冲及分层限流,并叠加limit_conn防慢攻击,再结合upstream均衡策略保障后端稳定。

实现请求速率平滑控制,核心是让突发流量被缓冲、匀速释放,而不是直接打到后端或瞬间拒绝。Nginx 本身不提供“动态调速”功能,但通过 limit_req 模块配合合理参数组合,能达成事实上的速率平滑效果。
用漏桶算法做基础平滑
限流不是简单卡死,而是靠漏桶机制削峰填谷——请求进来先排队或暂存,再按固定节奏放行。
- 在
http块定义共享限流区,推荐用$binary_remote_addr识别客户端:limit_req_zone $binary_remote_addr zone=smooth:10m rate=20r/s; - 在
location中启用,并设置burst缓冲容量:limit_req zone=smooth burst=40;
→ 允许最多 40 个请求暂存(相当于 2 秒缓冲),超出立即返回 503;不加nodelay时,队列内请求会严格按 20r/s 节奏释放。 - 所有 Nginx 实例必须共用同一
zone名称和大小,否则各节点限流状态不一致,平滑就失效。
按接口类型分层限流
统一限流会误伤轻量接口,也放纵高耗操作。应按路径或业务特征差异化配置。
- 对健康检查、配置拉取等低开销接口,放宽限制:
location /health { limit_req zone=health burst=100; } - 对报表导出、批量查询等高 CPU/IO 接口,收紧速率+小缓冲:
location /api/v1/export { limit_req zone=export rate=2r/s burst=4; } - 每个
zone独立定义,互不影响,整体流量曲线更贴合真实负载分布。
叠加连接数限制防慢攻击
只控请求数不够——恶意用户可能建几十个空闲长连接,占满 worker 连接池,导致合法请求排队甚至超时。
- 用
limit_conn控制单 IP 并发连接上限:limit_conn_zone $binary_remote_addr zone=conn_ip:10m;<br>limit_conn conn_ip 15;
- 搭配
limit_conn_log_level error和limit_conn_status 503,让超限连接明确失败,便于前端感知并退避重试。 - 该限制与
limit_req协同,共同守住入口资源水位,是平滑调度的底层保障。
配合 upstream 均匀分发已平滑的请求
限流后的请求,仍需稳定落到后端节点,避免倾斜放大抖动。
- 使用
least_conn或带健康检查的ip_hash(慎用)提升分发均衡性; - 设置
proxy_next_upstream error timeout http_503,自动摘除异常节点; - 避免在 upstream 中配置过短的
keepalive或过激的max_fails,防止正常波动触发误剔。


















