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

文章目录

  • 什么时候用令牌桶,什么时候用漏桶算法??
      • 先放结论
    • 两个算法一眼看懂
    • 什么时候选令牌桶?
    • 什么时候选漏桶?
    • 组合用法(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.mzph.cn/web/80257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp|实现获取手机摄像头权限,调用相机拍照实现人脸识别相似度对比,拍照保存至相册,多端兼容(APP/微信小程序)

基于uniapp以及微信小程序实现移动端人脸识别相似度对比,实现摄像头、相册权限获取、相机模块交互、第三方识别集成等功能,附完整代码。 目录 核心功能实现流程摄像头与相册权限申请权限拒绝后的引导策略摄像头调用拍照事件处理人脸识别集成图片预处理(Base64编码/压缩)调用…

OpenCV CUDA 模块中用于在 GPU 上计算两个数组对应元素差值的绝对值函数absdiff(

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 void cv::cuda::absdiff 是 OpenCV CUDA 模块中的一个函数,用于在 GPU 上计算两个数组对应元素差值的绝对值。 该函数会逐元素计算两…

Rust 数据结构:HashMap

Rust 数据结构:HashMap Rust 数据结构:HashMap创建一个新的哈希映射HashMap::new()将元组变成哈希表 访问哈希映射中的值哈希映射和所有权更新哈希映射重写一个值仅当键不存在时才添加键和值基于旧值更新值 散列函数 Rust 数据结构:HashMap …

【从设置到上传的全过程】本地多个hexo博客,怎么设置ssh才不会互相影响

偶然间,想多建一个博客,但电脑已经有一个博客了,怎么设置ssh才不会互相影响呢? 在 Windows 系统上设置多个 Hexo 博客的 SSH 配置,避免互相影响,通常户就需要为每个博客配置不同的 SSH 密钥,并…

【时时三省】(C语言基础)字符数组应用举例2

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 例题: 有3个字符串,要求找出其中“最大”者。 解题思路: 可以设一个二维的字符数组str,大小为320,即有3行20列(每一…

2025认证杯挑战赛第二阶段B题【 谣言在社交网络上的传播 】原创论文讲解(含完整python代码)

大家好呀,从发布赛题一直到现在,总算完成了认证杯数学中国数学建模网络挑战赛第二阶段B题目谣言在社交网络上的传播完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半…

Qt功能区:Ribbon使用

Ribbon使用 1. Ribbon功能区介绍1.1 样式 2. 基本功能区设置2.1 安装动态库(推荐)2.2 在MainWindow中使用Ribbon2.3 在QWidget中使用SARibbonBar2.4 创建Category和Pannel2.5 ContextCategory 上下文标签创建 2.6 ApplicationButton2.7 QuickAccessBar和…

Ubnutu ADB 无法识别设备的解决方法

1. 正确安装adb 下载地址 2. 检查 Linux 是否识别设备 lsusb通过上述指令,分别查询插入、断开设备的usb设备表,如下所示: # 插入设备 adbc:~$ lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 011:…

C# 实现雪花算法(Snowflake Algorithm)详解与应用

在现代分布式系统中,生成全局唯一的标识符(ID)是一个非常重要的问题。随着微服务架构和分布式系统的普及,传统的单机数据库生成 ID 的方式已无法满足高并发和高可用的需求。为了解决这个问题,Twitter 提出了 雪花算法&…

STM32+ESP8266连接onenet新平台

若该文为原创文章,转载请注明原文出处。 阿里云物联网平台无法开通了,所以尝试使用onenet平台。 一、硬件 1、STM32F103C8T6最⼩系统板 2、ESP-01S 3、DHT11 二、软件 1、KEIL5.29 2、Token生成工具 3、app inventor 三、原理 四、平台搭建 1、注…

深入解析Spring Boot与Redis集成:高效缓存实践

深入解析Spring Boot与Redis集成:高效缓存实践 引言 在现代Web应用开发中,缓存技术是提升系统性能的重要手段之一。Redis作为一种高性能的键值存储数据库,广泛应用于缓存、会话管理和消息队列等场景。本文将详细介绍如何在Spring Boot项目中…

Python自学笔记3 常见运算符

常用运算符 加减法 python的自动数据类型转换 整形转为浮点型 实数转为复数 数字类型不能和浮点数类型相加减 乘除法 数据转换基本同加减法, 但字符串可以和整数相加减,作用是字符串的自我复制 反斜杠 成员运算符 判断一个元素是不是一个序列的成员…

[特殊字符]接口测试用例设计指南:全面覆盖与精准验证

一、接口测试的核心价值 接口作为系统间通信的桥梁,其稳定性和准确性直接影响业务功能。通过科学设计的测试用例,可以提前暴露接口潜在缺陷,降低上下游系统的耦合风险。本文将系统讲解接口测试的用例设计策略,覆盖查询类接口与操…

[SpringBoot]Spring MVC(2.0)

紧接上文,这篇我们继续讲剩下的HTTp请求 传递JSON数据 简单来说:JSON就是⼀种数据格式,有⾃⼰的格式和语法,使⽤⽂本表⽰⼀个对象或数组的信息,因此JSON本质是字符串. 主要负责在不同的语⾔中数据传递和交换 JSON的语法 1. 数据在 键值对(Key/Value) …

锚点跳转跟踪#

一、html <div ref"computingref"><section id"section1"> </section><section id"section2"> </section><section id"section3"> </section> </div><div class"nav-list&q…

一文了解多模态大模型LLaVA与LLaMA的概念

目录 一、引言 二、LLaVA与LLaMA的定义 2.1 LLaMA 2.2 LLaVA 2.3 LLaVA-NeXT 的技术突破 三、产生的背景 3.1 LLaMA的背景 3.2 LLaVA的背景 四、与其他竞品的对比 4.1 LLaMA的竞品 4.2 LLaVA的竞品 五、应用场景 5.1 LLaMA的应用场景 5.2 LLaVA的应用场景 六…

【LLM】大模型算力基础设施——核心硬件GPU/TPU,架构技术NVLink/RDMA,性能指标FP64/FLOPS(NVIDIA Tesla型号表)

【LLM】大模型算力基础设施——核心硬件GPU/TPU&#xff0c;架构技术NVLink/RDMA&#xff0c;性能指标FP64/FLOPS&#xff08;NVIDIA Tesla型号表&#xff09; 文章目录 1、核心硬件GPU/TPU&#xff0c;NVIDIA Tesla2、集群架构设计 NVLink / RDMA / Alluxio3、性能关键指标&am…

spark的Standalone模式介绍

Apache Spark 的 Standalone 模式是其自带的集群管理模式&#xff0c;无需依赖外部资源管理器&#xff08;如 YARN 或 Mesos&#xff09;&#xff0c;可快速部署和运行 Spark 集群。以下是对 Standalone 模式的详细介绍&#xff1a; 1. 核心组件 Master 节点 集群的主控制器…

YOLOv7训练时4个类别只出2个类别

正常是4个类别&#xff1a; 但是YOLOv7训练完后预测总是只有两个类别&#xff1a; 而且都是LFM和SFM 我一开始检查了下特征图大小&#xff0c;如果输入是640*640的话&#xff0c;三个尺度特征图是80*80,40*40,20*20&#xff1b;如果输入是416*416的话&#xff0c;三个尺度特征…

【Unity】用事件广播的方式实现游戏暂停,简单且实用!

1.前言 在做Unity项目的时候&#xff0c;要考虑到“游戏暂停”的功能&#xff0c;最直接的办法是修改游戏的Time.TimeScale 0f。但是这种方式的影响也比较大&#xff0c;因为它会导致游戏中很多程序无法正常运行。 于是我就有了一个想法&#xff0c;在游戏中想要暂停的对象&…