news 2026/4/8 21:09:37

漏桶算法详解:从原理到实现,为什么它仍是限流的重要一环?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
漏桶算法详解:从原理到实现,为什么它仍是限流的重要一环?

目录

      • 一、什么是漏桶算法?
      • 二、动手实现一个简单的漏桶限流器
      • 三、漏桶的优缺点
      • 四、Q&A:个人思考
        • Q1:严格控制每个请求的执行间隔真的有必要吗?漏桶还有使用场景吗?
        • Q2:令牌桶和漏桶到底有什么区别?
        • Q3:既然漏桶本质是“队列 + 定时任务”,那能不能直接用定时任务替代?
        • Q4:如果限流超过 1000 QPS 怎么办?
        • Q5:“为什么令牌桶允许突发,漏桶不允许?”

在应对突发流量时,限流是我们保障系统稳定性的第一道防线。常用的限流工具如Google Guava RateLimiterAlibaba SentinelRedis + Lua 脚本(分布式限流)Nginx 限流Spring Cloud Gateway等,虽然功能各异,但底层大多基于四种经典算法:计数器(Counter)、滑动窗口(Sliding Window)、漏桶(LeakyBucket)和令牌桶(Token Bucket)。深入理解这些算法的原理,有助于我们更合理地选择和使用限流工具。

上一篇文章我们聊了令牌桶,今天来聊聊它的“孪生兄弟”——漏桶算法(Leaky Bucket)。本文将从以下几个方面展开:

  • 什么是漏桶算法?
  • 手动实现一个简单的漏桶
  • 漏桶的优缺点分析
  • 常见问题与作者思考(Q&A)

一、什么是漏桶算法?

漏桶算法(Leaky Bucket Algorithm)是一种经典的流量整形(Traffic Shaping)和限流(Rate Limiting)算法。它的核心思想非常直观:

无论输入流量多么突发或不均匀,输出流量始终保持恒定速率。

就像一个底部有小孔的水桶:

  • 水可以快速倒入(请求可以瞬间涌入);
  • 但水只能以固定速度从底部小孔漏出(系统以固定速率处理请求);
  • 桶有固定容量,若水倒得太快导致溢出,则多余水流直接丢弃(请求被拒绝)。

这种机制天然具备平滑突发流量、保护下游系统的能力。


二、动手实现一个简单的漏桶限流器

在后端开发中,我们通常用一个有界队列来模拟漏桶:

  • 桶容量= 队列的最大长度;
  • 漏水速率= 后台定时任务以固定间隔从队列头部取出并“处理”请求。

伪代码大概长这样:

publicclassLeakyBucketLimiter{//用队列模拟桶(注意:实际要存的是要执行的任务,作者用Boolean代替了)privatefinalArrayBlockingQueue<Boolean>queue;//定时器privatefinalScheduledExecutorServicescheduler;//构造函数publicLeakyBucketLimiter(intcapacity,intrate){//参数校验if(capacity<=0||rate<=0){thrownewIllegalArgumentException("参数需要大于0");}//初始化桶this.queue=newArrayBlockingQueue<Boolean>(capacity);//计算漏水间隔,确保每个请求漏出的时间间隔相同longinterval=1000L/rate;//创建一个单线程调度器this.scheduler=Executors.newSingleThreadScheduledExecutor(r->{Threadt=newThread("LeakyBucketLimiter-Thread");//线程设置为守护线程,确保JVM退出时,线程也能退出t.setDaemon(true);returnt;});scheduler.scheduleAtFixedRate(this::leak,//要执行的任务interval,//初始延迟interval,//间隔时间TimeUnit.MILLISECONDS);}//提交请求publicbooleantryAcquire(){//实际要把任务加入队列,这里只是模拟returnqueue.offer(true);}privatevoidleak(){//从队头移除一个元素,模拟漏水queue.poll();}//关闭定时器,并清空队列publicvoidshutdown(){scheduler.shutdown();queue.clear();}}

关于守护线程:守护线程(如 GC、JIT 编译线程)为用户线程服务。当所有非守护线程结束时,JVM 会直接退出,不再等待守护线程完成。

使用示例:

// 每秒最多 3 个请求,桶容量 = 3SimpleLeakyBucketlimiter=newSimpleLeakyBucket(3,3);for(inti=0;i<8;i++){if(limiter.tryAcquire()){//实际要把任务放进队列!!!System.out.println(" 请求 "+i+" 被接受");}else{System.out.println(" 请求 "+i+" 被拒绝(桶满)");}Thread.sleep(100);// 每 100ms 发一个请求(10 QPS > 3 QPS)}

是不是很简单?核心逻辑就是:请求先入队,后台线程匀速消费


三、漏桶的优缺点

优点:请求稳定,能很好利用性能,保护下游系统。

缺点:无法应对突发流量,容易积压请求,大量请求被拒绝。

正因为这些限制,纯漏桶在现代 Web 服务中较少单独使用,更多被令牌桶滑动窗口取代。但在某些特定场景(如硬件对接、音视频帧率控制、流量整形网关),漏桶仍是不可替代的选择。


四、Q&A:个人思考

Q1:严格控制每个请求的执行间隔真的有必要吗?漏桶还有使用场景吗?

我觉得没必要,只有定时执行的场景(音/视频控制帧率)能用到,绝大部分都用令牌桶和滑动窗口。(你们怎么看?)

Q2:令牌桶和漏桶到底有什么区别?
  • 漏桶:把请求放到缓冲队列,让它按时执行,队满拒绝。
  • 令牌桶:按时往桶里发放令牌,到桶里拿令牌,能拿到令牌就能执行,否则拒绝。
Q3:既然漏桶本质是“队列 + 定时任务”,那能不能直接用定时任务替代?

漏桶 =有界队列 + 定时消费 + 入口拒绝。如果只用定时任务处理无界队列,会导致请求堆积、内存爆炸、延迟飙升——这已经不是限流,而是“慢消费”。真正的限流必须在入口快速拒绝超量请求

Q4:如果限流超过 1000 QPS 怎么办?

rate > 1000时,interval = 1000 / rate可能小于 1ms,超出操作系统调度精度。此时应放弃高频定时器,改用懒更新 + 纳秒时间戳的方式(类似令牌桶的实现),在每次请求时动态计算可释放的配额。

Q5:“为什么令牌桶允许突发,漏桶不允许?”

令牌桶可以预存令牌,空闲时攒下的令牌可用于突发;
漏桶的队列只能排队等待,即使空闲,新请求也必须等系统按节奏“漏水”才能腾出空间。
但注意:漏桶允许“有限突发”——只要不超过桶容量!


🐾 欢迎留言讨论!作者爱思考,也爱和你一起探索技术本质~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/8 8:17:36

快速上手LiteLoaderQQNT插件开发:从零创建个性化主题

快速上手LiteLoaderQQNT插件开发&#xff1a;从零创建个性化主题 【免费下载链接】LiteLoaderQQNT LiteLoaderQQNT - QQNT的插件加载器&#xff0c;允许用户为QQNT添加各种插件以扩展功能&#xff0c;如美化主题。 项目地址: https://gitcode.com/gh_mirrors/li/LiteLoaderQQ…

作者头像 李华
网站建设 2026/4/2 19:59:39

智能家居自动化终极指南:从零搭建完整的AI控制中心

在当今数字化时代&#xff0c;智能家居自动化已成为提升生活品质的重要途径。本指南将带您从零开始&#xff0c;构建一个功能完整的AI控制中心&#xff0c;实现家居设备的智能化管理和自动化控制。 【免费下载链接】go2_ros2_sdk Unofficial ROS2 SDK support for Unitree GO2 …

作者头像 李华
网站建设 2026/4/7 22:27:36

【强化学习实验】- 策略梯度算法

1.实验内容 策略梯度算法文章中2.2 策略梯度算法。 通俗总结 ① 优胜劣汰 ② 学如逆水行舟&#xff0c;不进则退。 2.实验目标 2.1 构建策略模型 class PolicyNet(torch.nn.Module):def __init__(self, state_dim, hidden_dim, action_dim):super(PolicyNet, self).__init…

作者头像 李华
网站建设 2026/3/26 8:28:38

揭秘LLama-Factory底层架构:如何统一支持LLaMA/Qwen/Baichuan等模型

揭秘LLama-Factory底层架构&#xff1a;如何统一支持LLaMA/Qwen/Baichuan等模型 在大语言模型&#xff08;LLM&#xff09;快速演进的今天&#xff0c;一个现实问题摆在开发者面前&#xff1a;为什么微调一个模型要写一套代码&#xff0c;换另一个就得重来&#xff1f;明明都是…

作者头像 李华
网站建设 2026/4/8 9:21:29

Qwen-Image专业级图像生成模型支持1024×1024输出

Qwen-Image&#xff1a;专业级图像生成的技术跃迁 在广告公司加班到深夜的设计师&#xff0c;正为一个融合东方美学与未来科技感的品牌视觉方案焦头烂额。客户要求“青花瓷色调的赛博朋克风格”&#xff0c;还要加入书法元素和动态光影。过去&#xff0c;这可能需要数轮手绘草图…

作者头像 李华
网站建设 2026/4/4 13:30:26

PID调试技巧:定位HunyuanVideo-Foley运行时进程卡顿问题

PID调试技巧&#xff1a;定位HunyuanVideo-Foley运行时进程卡顿问题 在AI驱动的视频内容生产链条中&#xff0c;音效生成正从“人工精修”迈向“自动合成”。腾讯混元团队推出的 HunyuanVideo-Foley 正是这一趋势下的代表性系统——它能根据视频画面自动生成脚步声、碰撞声、环…

作者头像 李华