令牌桶和漏桶算法使用场景解析
文章目录
- 什么时候用令牌桶,什么时候用漏桶算法??
- 先放结论
- 两个算法一眼看懂
- 什么时候选令牌桶?
- 什么时候选漏桶?
- 组合用法(90% 的真实系统都会这么干)
- 小结记忆
- 对令牌桶和漏桶组合用法再次详细叙述一下,以小红书生活社区系统为例子
- 为什么要 **“令牌桶 → 漏桶”** 组合?
- 1. 小红书请求链路示例
- 2. 组合在小红书的 **四个高频场景**
- 3. 配置与调优步骤(落地到小红书)
- 4. 代码/配置片段示意
- 5 · 常见误区 & 小红书踩坑实录
什么时候用令牌桶,什么时候用漏桶算法??
先放结论
场景特征 | 令牌桶(Token Bucket) | 漏桶(Leaky Bucket) |
---|---|---|
是否允许突发流量 | ✔ 允许,可在桶里先攒“额度”,瞬时放量 | ✘ 不允许,出流量永远是匀速 |
对下游的压力 | 瞬时可能出现高并发,需要下游有一定缓冲或弹性 | 始终平滑,几乎不会压垮下游 |
对实时性/时延要求 | 突发时延小,整体时延可控 | 峰值被“削平”,高峰请求会排队、时延增大 |
典型用例 | API 网关限流、微服务之间“削峰”但保留突发、手机套餐计费 | 交换机/路由器排队、日志写入磁盘、打印任务、银行转账出账口 |
两个算法一眼看懂
关键词 | 令牌桶 | 漏桶 |
---|---|---|
本质 | “拿令牌才可通过” | “进水随意,出水匀速” |
控制维度 | 入流(允许多久发多少) | 出流(确保永远固定速率) |
可配置项 | 生成速率 r、桶容量 b | 漏出速率 r、桶容量 b |
能否积攒额度 | 可以:桶里最多存 b 个令牌 | 可以:桶里最多排队 b 个请求 |
流量视角 | 突发→滑动平均 ≤ r | 任何时刻 ≤ r |
什么时候选令牌桶?
- 业务本身就是“偶有高峰”
例:电商秒杀开始前 5 秒,令牌桶能攒够令牌,瞬间放行指定量请求;后续再匀速补充。 - 下游能短暂扩容或有缓冲区
比如使用异步队列、K8s 自动扩缩容,可吃掉短时突发。 - 需要按“总量 + 峰值”计费/统计
运营商对流量计费:保证平均速率,但允许你瞬时用掉“未用额度”。 - API 限流希望“好人优先”
正常流量积攒令牌,机器人/爬虫持续刷会很快耗尽令牌,被限速。
一句话:令牌桶在乎“总量控制 + 瞬时弹性”。
什么时候选漏桶?
- 下游“吃不了”任何峰值,只能匀速消费
打印机、磁带机、磁盘顺写、第三方支付接口 QPS 固定。 - 希望彻底削峰平谷,保证稳定输出
视频流推送、实时音频、网络芯片队列,抖动越小越好。 - 时延可被牺牲换取稳定
排队时间增加也没关系,例如批量日志落盘。 - 实现简单、资源可预估
只要求一个固定速率,不需要动态计算剩余令牌。
一句话:漏桶在乎“绝对平滑 + 下游安全”。
组合用法(90% 的真实系统都会这么干)
- 入口令牌桶 —— 允许合规突发,把“洪峰”削到可控范围。
- 出口漏桶 —— 对真正娇贵的依赖再做一次匀速下沉。
这样既不失灵活性,又能保护最脆弱的环节。很多 API 网关、CDN、大型分布式系统限流都是“先令牌桶,后漏桶”。
小结记忆
- 令牌桶:能攒钱、能一次性花;平均不能超标。
- 漏桶:只能领死工资;永远 1、1、1… 匀速走。
选哪个?看你要不要“突发权”。如果答案是“要”—→令牌桶;如果答案是“绝不能”—→漏桶。
对令牌桶和漏桶组合用法再次详细叙述一下,以小红书生活社区系统为例子
为什么要 “令牌桶 → 漏桶” 组合?
在真实的大型社区里——小红书就是典型——没有一种单独的限流算法能同时满足「用户体验」和「核心依赖安全」 两个目标:
目标 | 令牌桶能做到 | 漏桶能做到 |
---|---|---|
秒级突发场景(双 11、明星发笔记秒赞)依然“秒开” | ✔ | ✘ |
保护下游(数据库、推荐 RPC、支付)绝不被瞬时打爆 | ✘ | ✔ |
所以工业界普遍做法是:入口先令牌桶,出口再漏桶。下面用小红书的典型流量路径来拆一遍。
1. 小红书请求链路示例
App/Web ➜ CDN ➜ API Gateway ➜ Notes Service ➜│ │(令牌桶限流) (漏桶匀速入库 + MQ)
-
API Gateway / 边缘网关(令牌桶)
- 粒度:用户 ID + 接口(
/notes/publish
、/notes/like
等) - 配置示例:
- 桶容量 B = 120(允许 2 分钟的剩余额度)
- 令牌速率 R = 60 req/min(每人每分钟 60 次发帖接口)
- 效果:
- 正常人偶尔连点「发布」也能秒过。
- 连续脚本刷请求会瞬间耗空令牌,得到 429。
- 粒度:用户 ID + 接口(
-
业务微服务(漏桶)
- 场景:
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. 配置与调优步骤(落地到小红书)
- 抓历史峰值
- 查询「双 11」「618」「明星生日」当天 每 10 秒 的 QPS 波峰。
- 先配令牌桶
B ≈ R × 可接受峰值持续秒数
(可逆算为「用户能连点多少次不被限」)。
- 测后端极限
- 对 MySQL / ES / 推荐 RPC 压测,得出
L_max
。
- 对 MySQL / ES / 推荐 RPC 压测,得出
- 配漏桶
L = 0.8 × L_max
预留 20 % 余量。Q = L × 回滚/降级开销秒数
(如 4 秒)。
- 双阈值监控
- 队列长度 > 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;并且 每个微服务自己兜底、监控可观测、溢出有降级。
相关文章:
令牌桶和漏桶算法使用场景解析
文章目录 什么时候用令牌桶,什么时候用漏桶算法??先放结论 两个算法一眼看懂什么时候选令牌桶?什么时候选漏桶?组合用法(90% 的真实系统都会这么干)小结记忆 对令牌桶和漏桶组合用法再次详细叙述…...
轻量、优雅、高扩展的事件驱动框架——Hibiscus-Signal
在现代企业级应用中,事件驱动架构(EDA)已成为解耦系统、提升扩展性的利器。今天给大家推荐一个非常优秀的国产轻量级事件驱动框架 —— Hibiscus Signal,它不仅天然整合 Spring Boot,还提供完整的事件生命周期支持&…...

SEO 优化实战:ZKmall模板商城的 B2C商城的 URL 重构与结构化数据
在搜索引擎算法日益复杂的今天,B2C商城想要在海量信息中脱颖而出,仅靠优质商品和营销活动远远不够。ZKmall模板商城以实战为导向,通过URL 重构与结构化数据优化两大核心策略,帮助 B2C 商城实现从底层架构到搜索展示的全面升级&…...
2020CCPC河南省赛题解
A. 班委竞选 签到题,模拟。 #include <bits/stdc.h> #define x first #define y second #define int long long //#define double long doubleusing namespace std; typedef unsigned long long ULL ; typedef pair<int,int> PII ; typedef pair<d…...

数字万用表与指针万用表使用方法及注意事项
在电子测量领域,万用表是极为常用的工具,数字万用表和指针万用表各具特点。熟练掌握它们的使用方法与注意事项,能确保测量的准确性与安全性。下面为您详细介绍: 一 、数字万用表按钮功能 > 进入及退出手动量程模式 每 按 […...
虚拟主播肖像权保护,数字时代的法律博弈
首席数据官高鹏律师团队 在虚拟主播行业蓬勃发展的表象之下,潜藏着一场关乎法律边界的隐形战争。当一位虚拟偶像的3D模型被非法拆解、面部数据被批量复制,运营方惊讶地发现——传统的肖像权保护体系,竟难以完全覆盖这具由代码与数据构成的“…...

【读代码】端到端多模态语言模型Ultravox深度解析
一、项目基本介绍 Ultravox是由Fixie AI团队开发的开源多模态大语言模型,专注于实现音频-文本的端到端实时交互。项目基于Llama 3、Mistral等开源模型,通过创新的跨模态投影架构,绕过了传统语音识别(ASR)的中间步骤,可直接将音频特征映射到语言模型的高维空间。 核心优…...

RabbitMQ工作流程及使用方法
一、什么是RabbitMQ RabbitMQ 是一款基于 AMQP(高级,消息队列协议) 的开源消息中间件,专为分布式系统设计,用于实现应用程序间的异步通信,其核心功能是通过 消息代理(Message Broker&…...
Java 面向对象进阶:解锁多态、内部类与包管理
Java 面向对象进阶:解锁多态、内部类与包管理 🔑 在 Java 的面向对象编程中,多态赋予了对象“多种形态”的能力,内部类提供了更精细的代码组织方式,而包则帮助我们管理和组织大量的类。今天,我们将深入探讨…...

算法:分治法
实验内容 在一个2kⅹ2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称该方格为特殊方格,且称该棋盘为一特殊棋盘。 显然,特殊方格出现的位置有4k 种情况,即k>0,有4k 种不同的特殊棋盘 棋盘覆盖:…...

MySQL初阶:sql事务和索引
索引(index) 可以类似理解为一本书的目录,一个表可以有多个索引。 索引的意义和代价 在MySQL中使用select进行查询时会经过: 1.先遍历表 2.将条件带入每行记录中进行判断,看是否符合 3.不符合就跳过 但当表中的…...

docker部署第一个Go项目
1.前期准备 目录结构 main.go package mainimport ("fmt""github.com/gin-gonic/gin""net/http" )func main() {fmt.Println("\n .::::.\n .::::::::.\n :::::::::::\n …...
day27 python 装饰器
目录 一、装饰器的基本概念 示例:用装饰器优化质数查找函数 二、装饰器的高级用法 1. 支持任意参数的装饰器 2. 装饰器的返回值处理 在 Python 编程中,装饰器是一个非常强大的功能,它可以让其他函数或方法在不需要做任何代码修改的前提下…...

Visual Studio2022跨平台Avalonia开发搭建
由于我已经下载并安装了 VS2022版本,这里就跳过不做阐述。 1.安装 Visual Studio 2022 安装时工作负荷Tab页勾选 “.NET 桌面开发” 和“Visual Studio扩展开发” ,这里由于不是用的微软的MAUI,所以不用选择其他的来支持跨平台开发&a…...

css iconfont图标样式修改,js 点击后更改样式
背景: 在vue项目中,通过点击/鼠标覆盖,更改选中元素的样式,可以通过js逻辑,也可以根据css样式修改。包括以下内容:iconfont图标的引入以及使用,iconfont图标样式修改【导入文件是纯白࿰…...

开源项目实战学习之YOLO11:12.4 ultralytics-models-sam-memory_attention.py源码分析
👉 点击关注不迷路 👉 点击关注不迷路 👉 另外,前些天发现了一个巨牛的AI人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。感兴趣的可以点击相关跳转链接。 点击跳转到网站。 ultralytics-models-sam 1.sam-modules-memory_attention.pyblocks.py: 定义模…...

【沉浸式求职学习day42】【算法题:滑动窗口】
沉浸式求职学习 长度最小的子数组水果成篮 关于算法题:滑动窗口的几个题目 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组…...

LIIGO ❤️ RUST 12 YEARS
LIIGO 💖 RUST 12 YEARS 今天是RUST语言1.0发布十周年纪念日。十年前的今天,2015年的今天,Rust 1.0 正式发行。这是值得全球Rust支持者隆重纪念的日子。我借此机会衷心感谢Rust语言创始人Graydon Hoare,Mozilla公司,以…...

Linux基础开发工具二(gcc/g++,自动化构建makefile)
3. 编译器gcc/g 3.1 背景知识 1. 预处理(进行宏替换/去注释/条件编译/头文件展开等) 2. 编译(生成汇编) 3. 汇编(生成机器可识别代码) 4. 连接(生成可执行文件或库文件) 3.2 gcc编译选项 格式 : gcc …...
Linux zip、unzip 压缩和解压
zip 命令用于压缩文件,压缩后的文件后缀名为 .zip 。 对应的解压命令是 unzip 。 测试用的目录结构如下, userzn:~/test$ tree . ├── folder1 │ ├── folder111 │ │ └── file1.txt │ └── main1.c ├── folder2 │ ├── …...
muduo库TcpConnection模块详解——C++
muduo库中的TcpConnection模块详解 TcpConnection是muduo库中处理TCP连接的核心模块,负责管理单个TCP连接的生命周期、数据读写、状态转换以及事件回调。每个TCP连接对应一个TcpConnection对象,其设计体现了高性能、线程安全和灵活回调的特点。 一、核心…...
Node.js 源码架构详解
Node.js 的源码是一个庞大且复杂的项目,它主要由 C 和 JavaScript 构成。要完全理解每一部分需要大量的时间和精力。我会给你一个高层次的概述,并指出一些关键的目录和组件,帮助你开始探索。 Node.js 的核心架构 Node.js 的核心可以概括为以…...

全局异常处理:如何优雅地统一管理业务异常
在软件开发中,异常处理是保证系统健壮性的重要环节。一个良好的异常处理机制不仅能提高代码的可维护性,还能为使用者提供清晰的错误反馈。本文将介绍如何通过全局异常处理和业务异常统一处理来编写更加优雅的代码。 一、传统异常处理的痛点 1.1 典型问…...
分布式锁: Redis和ZooKeeper两种分布式锁对比
在分布式系统中,分布式锁是协调多节点共享资源访问的核心机制。Redis 和 ZooKeeper 是两种常用的分布式锁实现方案,但两者的设计理念、适用场景和优缺点存在显著差异。本文将从 一致性模型、性能、可靠性、实现原理 等维度进行对比,并提供技术…...

动态规划-LCR 166.珠宝的最大价值-力扣(LeetCode)
一、题目解析 frame二维矩阵中每个值代表珠宝的价值,现在从左上角开始拿珠宝,只能向右或向下拿珠宝,到达右下角时停止拿珠宝,要求拿的珠宝价值最大。 二、算法解析 1.状态表示 我们想要知道的是到达[i,j]为位置时的最大价值&am…...

JDBC实现模糊、动态与分页查询的详解
文章目录 一. 模糊查询1. Mysql的写法2. JDBC的实现 二. 动态条件查询1. 创建生成动态条件查询sql的方法2. 完整的动态条件查询类以及测试类 三. 分页查询1. 什么是分页查询?2. 分页查询的分类3. MySQL的实现4. JDBC实现4.1. 创建page页4.2. 分页的实现 本章来讲一下…...

域环境信息收集技术详解:从基础命令到实战应用
引言 在企业网络环境中,Active Directory (AD)域服务是微软提供的集中式目录服务,用于管理网络中的用户、计算机和其他资源。对于信息安全专业人员来说,熟练掌握域环境信息收集技术至关重要,无论是进行渗透测试、安全评估还是日常…...
nodejs特性解读
单线程和事件驱动架构 参考 程序员dd-事件驱动架构 it-老齐-事件驱动架构 总结...

【C++ Qt】布局管理器
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 🤔绪论: 在Qt开发中,界面布局的合理设计是提升用户体验的关键。早期,开发者常采用绝对定位的方式摆放控件,即通…...

vscode用python开发maya联动调试设置
如何在VScode里编写Maya Python脚本_哔哩哔哩_bilibili1 包括1,maya的python全面在vscode支持,2,通过mayacode发送到maya,3同步调试 import maya.cmds as cmds 1、让 maya.cmds编译通过 下载Autodesk_Maya_2018_6_Update_DEVK…...