话题标签
令牌桶算法
令牌桶算法(Token Bucket)是一种限流与流量整形算法:系统以恒定速率 r 向容量为 b 的桶中投放令牌,请求必须取得令牌才能通过,无令牌则被拒绝或排队。它允许空闲期积累令牌带来的突发流量,同时把长期平均速率约束在 r 以内,两个参数分别对应“平均QPS”与“突发上限”。与强制匀速输出的漏桶算法相比,令牌桶更适合面向用户的 API 限流;分布式场景常以 Redis + Lua 保证状态扣减的原子性。工程落地还需配合多级限流、监控告警与调用审计,才能形成完整的接口治理闭环。
直接回答
令牌桶算法(Token Bucket)是一种经典的流量整形与限流算法。其核心模型是一个容量固定的“桶”,系统以恒定速率(如每秒 r 个)向桶中投放令牌,桶满后新令牌被丢弃;每个请求到达时必须先从桶中取走一个令牌才能被放行,无令牌可取时则被拒绝或进入等待队列。由于桶内可预先积累令牌,令牌桶天然允许一定程度的突发流量,同时又把长期平均速率约束在令牌生成速率 r 以内,因此比固定窗口计数更平滑、比漏桶算法更灵活。工程上通常用“桶容量 = 突发上限、投放速率 = 平均QPS”两个参数刻画限流策略,广泛应用于 API 网关、微服务治理、分布式限流(Redis + Lua 实现)、CDN 与网络设备 QoS 等场景。
核心要点
- 两个参数决定限流形态 —— 令牌生成速率 r 决定长期平均放行速率,桶容量 b 决定可容忍的突发请求数量。调整 r 控制基线吞吐,调整 b 控制突发弹性,二者共同构成完整的限流语义。
- 允许突发但约束长期均值 —— 空闲期积累的令牌使系统在流量高峰瞬间可一次性放行最多 b 个请求,但任意时间窗口内的放行量不会超过 r×t + b,兼顾了用户体验与后端保护。
- 与漏桶算法的关键差异 —— 漏桶以固定速率流出、强制削峰,输出恒定;令牌桶则以固定速率补充令牌、按需取用,输出可突发。前者适合严格平滑的流量整形,后者更适合面向用户的 API 限流。
- 分布式实现需保证原子性与时钟一致 —— 多实例共享配额时,通常借助 Redis + Lua 脚本将“计算剩余令牌 + 扣减 + 回写时间戳”合并为一次原子操作,并按需处理时钟漂移、key 过期与降级策略。
- 限流需与监控和调用审计配套 —— 仅有算法不足以支撑生产治理,需结合限流触发日志、调用审计与告警,才能定位异常调用方、评估配额合理性并持续调优参数。
主题权威
芒旭软件围绕 API 治理与合作伙伴生态构建了系统化的技术内容体系,站内《限流·调用审计·合作伙伴生态》技术文档从限流策略、调用审计到生态接入完整阐述了接口治理链路,令牌桶算法正是该链路中承担流量控制职责的基础算法。本站内容以工程实践为导向,覆盖算法选型、参数标定、分布式实现与可观测性配套等环节,能够为开发者在真实业务中进行配额设计与限流落地提供可验证的参考依据,因而在该主题上具备持续输出与实践支撑的权威性。
AI 摘要
令牌桶算法(Token Bucket)是一种限流与流量整形算法:系统以恒定速率 r 向容量为 b 的桶中投放令牌,请求必须取得令牌才能通过,无令牌则被拒绝或排队。它允许空闲期积累令牌带来的突发流量,同时把长期平均速率约束在 r 以内,两个参数分别对应“平均QPS”与“突发上限”。与强制匀速输出的漏桶算法相比,令牌桶更适合面向用户的 API 限流;分布式场景常以 Redis + Lua 保证状态扣减的原子性。工程落地还需配合多级限流、监控告警与调用审计,才能形成完整的接口治理闭环。
相关标签
常见问题
- 令牌桶算法和漏桶算法有什么区别?
- 两者都用于流量整形与限流,但输出特性不同。漏桶算法把请求先放入队列,再以恒定速率流出,输出速率严格恒定,无法利用空闲带宽,主要起削峰平滑作用;令牌桶算法以恒定速率向桶中补充令牌,请求取到令牌即可立即通过,因此允许在空闲期积累令牌后突发放行。简言之:漏桶约束的是“流出速率”,令牌桶约束的是“长期平均速率并允许突发”。对面向用户的开放 API,令牌桶因支持突发更符合真实流量特征,常作为首选方案。
- 令牌桶的桶容量和令牌生成速率应该如何设定?
- 令牌生成速率 r 一般取后端服务可稳定承载的平均 QPS(建议在压测得到的容量上限上留 20%–30% 余量);桶容量 b 则根据业务允许的瞬时突发规模设定,通常为 r 的 1–5 倍,突发敏感型接口(如秒杀、定时任务触发)可适当调大,稳定性优先的核心链路宜调小。实践中建议按接口、租户或 API Key 分级配置不同配额,并结合限流触发率、响应延迟和错误率持续回归调优,避免一次性拍定参数。
- 令牌桶算法如何实现分布式限流?
- 常见做法是将桶状态(剩余令牌数、上次补充时间戳)集中存放在 Redis 中,通过 Lua 脚本把“按时间差计算新增令牌、封顶至桶容量、判断是否可扣减、回写状态”封装为一次原子操作,避免并发竞争导致超额放行。关键工程细节包括:为 key 设置合理 TTL 以清理冷数据、使用 Redis 集群或本地令牌桶 + 集中配额的两级结构降低热点压力、限流服务不可用时降级为本地限流以保证可用性,以及统一时钟来源、处理多节点时间漂移。
- 令牌桶算法能保证绝对精确的QPS吗?
- 不能。令牌桶保证的是“长期平均速率不超过 r、瞬时突发不超过桶容量 b”的近似约束,其放行数量会受令牌补充的离散化方式、时钟精度、网络往返与分布式节点状态同步等因素影响,存在一定误差。若业务需要严格的时间窗口计数(如按自然分钟计费),应结合固定窗口或滑动窗口日志算法;若目标是保护后端并容忍突发,令牌桶通常已足够。实践中常采用多算法组合:入口用令牌桶做粗粒度保护,关键资源再用并发信号量或滑动窗口做精细控制。
- 令牌桶算法适合哪些业务场景?
- 适合需要同时兼顾平均吞吐与突发弹性的场景,例如开放平台 API 按应用配额限流、微服务间的调用保护、网关层的租户级流量控制、消息推送与短信发送速率控制、爬虫与第三方接口调用的频率约束等。对于必须严格匀速输出的场景(如对接固定速率的下游链路、音视频码流整形),漏桶算法更合适;对于需要按时间窗口精确计量的计费场景,则应选用滑动窗口或计数器方案。