微服务限流实战: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 不排队等待,尽快处理或拒绝

rate、burst、nodelay 怎么直观理解

假设配置是:

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 或路径,通过 replenishRate 和 burstCapacity 控制令牌生成速率和桶容量。

小结

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

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

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

相关推荐
开开心心就好12 分钟前
本地文件搜索工具,双击Ctrl就能呼出搜索
java·服务器·前端·支持向量机·ffmpeg·音视频·模拟退火算法
独隅17 分钟前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
ByteCoder.24 分钟前
班前十分钟的清单,按体检引导单来写
java·服务器·前端·助播虾
海的透彻26 分钟前
如何让docker容器启动时用自定义的用户
java·docker·dubbo
疯狂学习GIS31 分钟前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
GG.WinGel42 分钟前
质数数目(蓝桥杯练习题)
java·数据结构·算法·青少年编程·蓝桥杯
泡泡糖的中文规格书1 小时前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui1 小时前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu
秋天的怀念_David1 小时前
算法一千零一夜 · 第十七夜 长街点灯
java·程序人生·算法
不吃鱼的羊1 小时前
如何应对恐惧
java