限流算法(令牌桶、漏桶)
限流是保护后端服务不被过量请求压垮的关键手段。NGINX 的限流模块基于两种经典算法实现。
漏桶算法(Leaky Bucket)
原理
nginx
请求 → 桶(固定容量) → 匀速处理 → 后端
↑
超出容量直接拒绝
- 桶容量固定,请求以任意速率进入
- 处理以恒定速率流出
- 桶满时新请求被拒绝
特点
- 平滑突发,强制匀速
- 适合后端处理能力恒定的场景
- NGINX 的
limit_req默认使用此算法
令牌桶算法(Token Bucket)
原理
nginx
令牌生成器 → 桶(固定容量)
↓
请求 → 消费令牌 → 通过
↓
无令牌 → 拒绝
- 令牌以固定速率生成
- 桶满时停止生成
- 请求需消耗令牌才能通过
- 允许一定程度的突发
特点
- 允许短时突发
- 长期平均速率受控
- 更适合真实业务场景
NGINX 中的实现
limit_req — 漏桶算法
nginx
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}
}
limit_req核心是漏桶算法。rate定义恒定处理速率,burst定义桶容量(允许排队的请求数)。
limit_conn — 并发连接数限制
text
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
limit_conn addr 10;
}
}
}
limit_conn限制同一 key 的并发连接数,是漏桶算法的另一种表现形式。
算法对比
| 特性 | 漏桶 | 令牌桶 |
|---|---|---|
| 突发处理 | 不允许 | 允许 |
| 速率控制 | 强制匀速 | 长期平均 |
| 适用场景 | 后端处理恒定 | 允许短突发 |
| NGINX 实现 | limit_req | 需配置 burst |
| 溢出行为 | 拒绝 | 拒绝 |
burst 参数的作用
模拟令牌桶效果
text
limit_req zone=api burst=20 nodelay;
burst=20— 允许最多 20 个请求排队(桶容量)nodelay— 排队的请求立即处理而非延迟- 配合
rate=10r/s,效果近似令牌桶
无
nodelay时请求按 rate 匀速处理(纯漏桶)。有nodelay时突发请求立即处理,近似令牌桶。
要点总结
- 漏桶算法强制匀速,不允许突发
- 令牌桶算法允许短时突发,长期平均受控
- NGINX 的
limit_req基于漏桶算法 burst+nodelay参数组合可模拟令牌桶效果limit_conn限制并发连接数- 选择算法需考虑后端处理能力和业务容忍度
📝 发现内容有误?点击此处直接编辑