当前位置: 首页 > news >正文

令牌桶和漏桶算法使用场景解析

文章目录

  • 什么时候用令牌桶,什么时候用漏桶算法??
      • 先放结论
    • 两个算法一眼看懂
    • 什么时候选令牌桶?
    • 什么时候选漏桶?
    • 组合用法(90% 的真实系统都会这么干)
      • 小结记忆
  • 对令牌桶和漏桶组合用法再次详细叙述一下,以小红书生活社区系统为例子
      • 为什么要 **“令牌桶 → 漏桶”** 组合?
    • 1. 小红书请求链路示例
    • 2. 组合在小红书的 **四个高频场景**
    • 3. 配置与调优步骤(落地到小红书)
    • 4. 代码/配置片段示意
    • 5 · 常见误区 & 小红书踩坑实录

什么时候用令牌桶,什么时候用漏桶算法??

先放结论

场景特征令牌桶(Token Bucket)漏桶(Leaky Bucket)
是否允许突发流量✔ 允许,可在桶里先攒“额度”,瞬时放量✘ 不允许,出流量永远是匀速
对下游的压力瞬时可能出现高并发,需要下游有一定缓冲或弹性始终平滑,几乎不会压垮下游
对实时性/时延要求突发时延小,整体时延可控峰值被“削平”,高峰请求会排队、时延增大
典型用例API 网关限流、微服务之间“削峰”但保留突发、手机套餐计费交换机/路由器排队、日志写入磁盘、打印任务、银行转账出账口

两个算法一眼看懂

关键词令牌桶漏桶
本质“拿令牌才可通过”“进水随意,出水匀速”
控制维度入流(允许多久发多少)出流(确保永远固定速率)
可配置项生成速率 r、桶容量 b漏出速率 r、桶容量 b
能否积攒额度可以:桶里最多存 b 个令牌可以:桶里最多排队 b 个请求
流量视角突发→滑动平均 ≤ r任何时刻 ≤ r

什么时候选令牌桶?

  1. 业务本身就是“偶有高峰”
    例:电商秒杀开始前 5 秒,令牌桶能攒够令牌,瞬间放行指定量请求;后续再匀速补充。
  2. 下游能短暂扩容或有缓冲区
    比如使用异步队列、K8s 自动扩缩容,可吃掉短时突发。
  3. 需要按“总量 + 峰值”计费/统计
    运营商对流量计费:保证平均速率,但允许你瞬时用掉“未用额度”。
  4. API 限流希望“好人优先”
    正常流量积攒令牌,机器人/爬虫持续刷会很快耗尽令牌,被限速。

一句话令牌桶在乎“总量控制 + 瞬时弹性”。


什么时候选漏桶?

  1. 下游“吃不了”任何峰值,只能匀速消费
    打印机、磁带机、磁盘顺写、第三方支付接口 QPS 固定。
  2. 希望彻底削峰平谷,保证稳定输出
    视频流推送、实时音频、网络芯片队列,抖动越小越好。
  3. 时延可被牺牲换取稳定
    排队时间增加也没关系,例如批量日志落盘。
  4. 实现简单、资源可预估
    只要求一个固定速率,不需要动态计算剩余令牌。

一句话漏桶在乎“绝对平滑 + 下游安全”。


组合用法(90% 的真实系统都会这么干)

  1. 入口令牌桶 —— 允许合规突发,把“洪峰”削到可控范围。
  2. 出口漏桶 —— 对真正娇贵的依赖再做一次匀速下沉。

这样既不失灵活性,又能保护最脆弱的环节。很多 API 网关、CDN、大型分布式系统限流都是“先令牌桶,后漏桶”。


小结记忆

  • 令牌桶:能攒钱、能一次性花;平均不能超标。
  • 漏桶:只能领死工资;永远 1、1、1… 匀速走。

选哪个?看你要不要“突发权”。如果答案是“要”—→令牌桶;如果答案是“绝不能”—→漏桶。

对令牌桶和漏桶组合用法再次详细叙述一下,以小红书生活社区系统为例子

为什么要 “令牌桶 → 漏桶” 组合?

在真实的大型社区里——小红书就是典型——没有一种单独的限流算法能同时满足「用户体验」和「核心依赖安全」 两个目标:

目标令牌桶能做到漏桶能做到
秒级突发场景(双 11、明星发笔记秒赞)依然“秒开”
保护下游(数据库、推荐 RPC、支付)绝不被瞬时打爆

所以工业界普遍做法是:入口先令牌桶,出口再漏桶。下面用小红书的典型流量路径来拆一遍。


1. 小红书请求链路示例

App/Web ➜ CDN ➜ API Gateway ➜ Notes Service ➜│                        │(令牌桶限流)                 (漏桶匀速入库 + MQ)
  1. API Gateway / 边缘网关(令牌桶)

    • 粒度:用户 ID + 接口(/notes/publish/notes/like 等)
    • 配置示例
      • 桶容量 B = 120(允许 2 分钟的剩余额度)
      • 令牌速率 R = 60 req/min(每人每分钟 60 次发帖接口)
    • 效果
      • 正常人偶尔连点「发布」也能秒过。
      • 连续脚本刷请求会瞬间耗空令牌,得到 429。
  2. 业务微服务(漏桶)

    • 场景Notes Service 里写数据库、调用内容审核、下发特点 feed 打分。
    • 实现
      入队:任意速率
      出队:固定 5 k/s → MySQL & Redis & AI 审核
      
    • 参数
      • 漏速 L = 5 000 req/s(后端表的写入 QPS 压测上限)
      • 桶深度 Q = 20 000(≈4 秒峰值缓冲)
    • 效果
      • 当明星空降带来 10 k/s 发布洪峰时,队列顶多攒 4 秒即被消化。
      • 如果洪峰持续更久,队列溢出触发降级(写失败重试 / 回退到异步草稿)。

2. 组合在小红书的 四个高频场景

场景入口令牌桶出口漏桶额外策略
笔记发布用户维度限流,允许一键连发图片转码、AI 审核匀速写入超队列 10 s 回退草稿,告知稍后发布
点赞/收藏用户-接口维度令牌,防止机器脚本点赞写 Redis,不需要漏桶;但写 MySQL 日志走漏桶后端异步批量合并落库
搜索热词IP + 用户令牌桶,挡住爬虫高频搜索ES 查询也做漏桶,匀速 2 k/s热词命中缓存直接返回
直播间打赏用户余额操作需闪电响应→入口令牌桶 + 内存预扣金额入账、流水写账务库用漏桶账务库用 XA 事务,漏速按 TPS 上限

3. 配置与调优步骤(落地到小红书)

  1. 抓历史峰值
    • 查询「双 11」「618」「明星生日」当天 每 10 秒 的 QPS 波峰。
  2. 先配令牌桶
    • B ≈ R × 可接受峰值持续秒数(可逆算为「用户能连点多少次不被限」)。
  3. 测后端极限
    • 对 MySQL / ES / 推荐 RPC 压测,得出 L_max
  4. 配漏桶
    • L = 0.8 × L_max 预留 20 % 余量。
    • Q = L × 回滚/降级开销秒数(如 4 秒)。
  5. 双阈值监控
    • 队列长度 > 0.6 Q:灰度告警,加实例。
    • 队列长度 > 0.9 Q:熔断低优接口或触发静默降级。

4. 代码/配置片段示意

# 网关级(Kong / Envoy)
rate_limiting:name: notes_publish_token_bucketcapacity: 120        # Btokens_per_interval: 60     # Rinterval: 60sredis_slot: user_id# Notes Service(Go 伪码)
leaky := NewLeakyBucket(leakRate = 5000,     // LqueueDepth = 20000,  // Q
)
for req := range inboundChan {if !leaky.Allow(req) {metrics.Publish("overflow")return ErrBusy             // 触发降级}process(req)                   // 写库 + 审核 + MQ
}

5 · 常见误区 & 小红书踩坑实录

#误区(Anti-Pattern)真实后果 / 事故现场根因分析 & 解决策略
1只做令牌桶,不做漏桶2024 年某明星直播带货高峰,瞬时发帖 QPS 从 3 k 飙到 12 k;MySQL 主从延迟 30 s,导致点赞丢失、推荐时序错乱令牌桶放行突发,却没人“刹车”数据库 → 下游被冲垮
2漏桶漏速设太小春节活动,漏速仅 2 k/s;排队深度 20 k 很快塞满,发布接口耗时 > 10 s,被大量用户投诉卡顿峰值持续时间被低估;队列深度设计与峰值不匹配
3把漏桶做在网关层“全局公用”统一队列里既有搜索也有发帖;一次搜索风暴让发帖延迟 5 s——出现“木桶效应”业务优先级不同,却共用同一桶
4令牌桶容量(B)设过大群控脚本低频养号,10 min 内攒满 600 token,随后一键爆发 → 机器流量混在真人里逃过风控运维按“用户体验”放大 B,却忽视恶意攒桶
5令牌桶按 IP 而非用户限流学校/公司 NAT 出口下所有用户共享同一 IP,晚高峰点赞被误杀(429)多人共用 IP → token 争抢
6漏桶没有溢出策略活动推送 Bug 触发 50 k/s 写库,队列溢出后 JVM 直接 OOM队列满时仍强行入列
7未监控桶内指标一次 Gradual Release 没人关注队列水位,5 分钟后才发现 MySQL 延迟;事故扩大队列长度、等待时长无可观测
8跨机房分布式令牌桶未同步A 机房峰值被挡住,B 机房因未同步令牌被打爆;两边用户体验不一致本地缓存令牌导致“各自为政”
9漏桶排队里混入长耗时任务AI 审核超时 2 s,阻塞后面的 1000 条快速写入请求漏桶只是匀速出队,内部仍可能被慢请求“撑爆”
10冷热启停未预热令牌桶服务重启后令牌桶空,导致 10 s 内 90 % 用户请求 429冷启动没有令牌

经验总览:先用数据推“峰值 × 持续时间”,再对照下游极限设 B, R, L, Q;并且 每个微服务自己兜底、监控可观测、溢出有降级

http://www.xdnf.cn/news/504163.html

相关文章:

  • HDCleaner:深度清理与优化,提升系统性能
  • 六、磁盘划分与磁盘配额
  • Redis 发布订阅模式深度解析:原理、应用与实践
  • AI:人形机器人一定是人的形状吗?
  • 超长文本能取代RAG吗
  • 计算机视觉与深度学习 | Python实现EMD-SSA-VMD-LSTM时间序列预测(完整源码和数据)
  • 深入探讨 Java Switch Expressions
  • 期望是什么:(无数次的均值,结合概率)21/6=3.5
  • AI大模型(一)embedding模型的基础使用
  • AGI大模型(21):混合检索之混合搜索
  • Git Worktree 使用
  • 【Einops】Einops rearrange方法详解
  • C# 创建线程的方式
  • 一字典两世界:优雅移除 `NSDictionary` 指定键的最佳实践
  • 编程基础:什么是变量
  • 《 C语言中const修饰指针变量的用法与解析》
  • 解决米勒补偿右边零点的方法
  • 【蓝桥杯省赛真题51】python石头运输 第十五届蓝桥杯青少组Python编程省赛真题解析
  • mcp学习笔记
  • day 28
  • ECS/GEM是半导体制造业的标准通信协议中host和equipment的区别是什么,在交互过程中,如何来定位角色谁为host,谁为equipment
  • Spring Boot 中 MyBatis 与 Spring Data JPA 的对比介绍
  • 【Python 算法零基础 3.递推】
  • 【C语言】链接与编译(编译环境 )
  • 配置ssh服务-ubuntu到Windows拷贝文件方法
  • Java Records:简洁的数据建模新方式
  • ubuntu 24.04安装ros1 noetic
  • 历史数据分析——中证白酒
  • 数据库3——视图及安全性
  • 计算机网络体系结构深度解析:从理论到实践的全面梳理