微服务限流实战:Nginx 漏桶与网关令牌桶

限流不是为了让系统"变慢",而是为了让系统在突发流量、恶意请求或超过承载能力时,仍然能保住核心服务。

一句话概括:限流是在入口处控制请求速度或并发数量,Nginx 常用漏桶算法控制请求流出速率,Spring Cloud Gateway 常用令牌桶算法决定请求是否允许通过。


外部请求
入口限流
Tomcat

最大连接数
Nginx

漏桶限速
Nginx

连接数限制
Gateway

令牌桶限流
自定义拦截器
请求按固定速率进入后端
拿到令牌才允许通过

为什么要限流

项目中做限流一般有两个原因:

  1. 业务确实有突发流量:比如优惠券抢购,平时 QPS 只有 10 到 50,活动时瞬间到 2000。
  2. 防止恶意刷接口:比如登录、短信、下单、支付等接口被频繁请求。

面试回答时最好带具体业务场景,不要只说"为了保护系统"。

Nginx 漏桶限流

漏桶算法可以想成一个桶:

  • 请求像水一样进入桶。
  • 桶按固定速率漏水。
  • 后端按固定速率处理请求。
  • 桶满后,多余请求等待或被丢弃。

未满
已满
突发请求进入
漏桶缓存请求
桶是否已满
请求进入桶中等待
请求被拒绝或延迟
按固定速率漏出
后端服务稳定处理

Nginx 常见配置思路:

nginx 复制代码
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

location /api/ {
    limit_req zone=perip burst=20 nodelay;
}

几个参数要能说清楚:

参数 含义
key 限流对象,比如客户端 IP
zone 共享存储区,用来保存访问状态
rate 最大访问速率,比如 10r/s
burst 突发请求容量,相当于桶大小
nodelay 不排队等待,尽快处理或拒绝

rateburstnodelay 怎么直观理解

假设配置是:

nginx 复制代码
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

location /api/ {
    limit_req zone=perip burst=20 nodelay;
}

可以这样理解:

  • rate=10r/s:稳定情况下,每秒最多按 10 个请求的速度处理。
  • burst=20:允许额外暂存 20 个突发请求。
  • 没有 nodelay:突发请求会排队,按 10r/s 慢慢放行。
  • nodelay:突发请求不排队等待,会尽快处理;超过 burst 的请求直接被限流。



瞬间进来 35 个请求
10 个按速率正常处理
20 个进入 burst 突发容量
是否配置 nodelay
排队等待

按固定速率放行
尽快处理突发请求
超过容量的 5 个请求
被拒绝或返回限流响应

这个例子比单纯背参数更好用。面试时只要说出"稳定速率 + 突发容量 + 是否排队",就基本讲清楚了。

Nginx 并发连接数限制

除了控制请求速率,Nginx 也能限制连接数:

nginx 复制代码
limit_conn perip 20;
limit_conn perserver 100;

含义:

  • perip 20:单个 IP 最多同时保持 20 个连接。
  • perserver 100:当前虚拟主机最多处理 100 个并发连接。

速率限制解决"请求来得太快",连接数限制解决"连接占用太多"。

Gateway 令牌桶限流

令牌桶算法的逻辑和漏桶不一样:

  • 系统按固定速率生成令牌。
  • 令牌放入令牌桶。
  • 桶满后暂停生成。
  • 请求必须先拿到令牌。
  • 没有令牌的请求会被阻塞或拒绝。



令牌生成器
按固定速率

生成令牌
令牌桶
请求进入网关
是否拿到令牌
请求放行
请求被限流

Spring Cloud Gateway 可以通过 RequestRateLimiter 做局部过滤器限流:

参数 含义
key-resolver 定义限流对象,比如 IP、路径、用户 ID
replenishRate 每秒填充令牌的平均速率
burstCapacity 令牌桶总容量

漏桶和令牌桶怎么选

对比点 漏桶算法 令牌桶算法
核心思想 请求按固定速率流出 拿到令牌才放行
突发流量 更平滑,削峰明显 支持一定突发能力
常见位置 Nginx Gateway
适合场景 控制后端稳定处理速率 允许短时间突发但限制总体速率

面试回答模板

可以这样答:

我们项目在活动接口上做过限流。平时 QPS 大概几十,活动高峰可能到 2000,为了防止突发流量打垮系统,在入口层做了限流。Nginx 侧用漏桶算法控制请求速率,让请求以固定速率进入后端,也可以限制单 IP 连接数。网关侧可以使用 Spring Cloud Gateway 的 RequestRateLimiter,底层是令牌桶算法,通过 key-resolver 指定限流对象,比如 IP 或路径,通过 replenishRateburstCapacity 控制令牌生成速率和桶容量。

小结

限流要讲业务背景,也要讲算法差异:

漏桶更强调平滑流出,令牌桶更强调拿令牌放行并允许一定突发。

项目回答里带上 QPS、限流位置和参数,比只背算法更像真实经验。

相关推荐
未秃头的程序猿13 分钟前
凌晨3点被叫醒:线上OOM,我用这套流程40分钟定位根因
java·jvm·后端
letisgo531 分钟前
JDK21 + Spring AI 2.0 入场指南:2026 年 Java 开发者 AI 架构全景图
java·ai·idea·jdk21
白仑色33 分钟前
Spring Boot 从切面统一控制事务
java·spring boot·aop·spring事务
Flynt42 分钟前
Java并行流,让我debug了一整天
java
DFT计算杂谈1 小时前
FeSe超薄膜在CaF2衬底上的电子结构DFT研究
java·服务器·前端
circuitsosk1 小时前
长文本与高并发下的Token“瘦身”策略:Prompt压缩与上下文窗口优化
java·前端·python·prompt·上下文窗口·token优化
岁岁养乐多1 小时前
LangChain4j 工厂模式
java·开发语言
星期一研究室1 小时前
从“能看”到“爱看”:用色彩心理学打造人人爱看的的专业文档🧩
微服务·产品·设计
小小小米粒1 小时前
idea常用搭配
java
吃饱了得干活1 小时前
Java Map 核心原理:从数据结构到 put/get 执行,一篇彻底讲透
java·后端