JCSprout 限流算法详解:漏桶算法与令牌桶算法原理及 Java 实战
文档教程后端【免费下载链接】JCSprout‍ Java Core Sprout : basic, concurrent, algorithm项目地址https://gitcode.com/gh_mirrors/jc/JCSprout点击查看免费下载限流Rate Limiting是应对高并发大流量的经典手段其核心目标并非提升吞吐而是在流量洪峰到来时保证核心应用的可用性让系统活下来。本文以 JCSprout 仓库中的限流算法文档为主体系统讲解漏桶算法与令牌桶算法两种主流方案的原理、适用场景与取舍并结合 GuavaRateLimiter的实战代码与仓库中的分布式限流方案带你完成从单机限流到分布式限流的完整认知闭环。为什么需要限流在高并发场景下系统的处理能力存在上限数据库连接数、线程池大小、下游服务的吞吐……当请求量远超系统承载能力时排队、超时、雪崩随之而来。限流的意义在于在请求进入系统核心处理逻辑之前主动将流量控制在可承受的范围内超出部分快速失败或排队从而保证应用至少可用。限流通常有以下两种经典方案漏桶算法Leaky Bucket令牌桶算法Token Bucket二者的核心差异在于漏桶算法强制匀速放行流量令牌桶算法则允许一定程度的突发流量。下面分别展开。漏桶算法强制匀速简单但粗暴算法原理漏桶算法的思想非常直观将流量看作水流先全部注入一个桶中桶的底部有一个固定速率的漏口水流按照恒定速率流出桶外。当流量进入速率超过流出速率时桶中的水待处理请求会积累桶有容量上限一旦溢出超出的流量请求直接丢弃。也就是说无论上游的流量如何波动经过漏桶后输出的流量永远是恒定的速率溢出部分的流量只能被抛弃。优缺点分析维度说明优点实现极其简单输出速率恒定能对下游提供非常平滑、稳定的流量缺点非常粗暴无法应对突发的大流量这里无法应对突发流量包含两层含义一是桶满后新来的突发请求会被直接丢弃二是即便桶未满突发流量进入桶后也只会以恒定速率流出突发请求依然要排队等待无法被快速消化。正因为漏桶对突发流量不友好当业务存在短时脉冲式请求且希望快速处理时就需要引入下一节的令牌桶算法。令牌桶算法支持突发兼顾平滑算法原理令牌桶算法的思想与漏桶相反按照恒定的速率向桶中放入令牌令牌积累在桶中桶有容量上限。每当一个请求经过时需要消耗一个或多个令牌才能被放行当桶中的令牌为 0 时请求则会被阻塞或快速失败。因此令牌桶的限速体现在放令牌的速率上而非强制输出速率上如果请求速率长期高于放令牌速率令牌会被耗尽请求被阻塞长期平均速率被限制在放令牌速率附近但如果一段时间没有请求桶中会积累满桶令牌此时一批突发请求到来可以一次性消耗积攒的令牌快速通过——这正是漏桶算法做不到的。先消费后付款令牌桶的透支机制note 令牌桶算法支持先消费后付款比如一个请求可以获取多个甚至全部的令牌但是需要后面的请求付费。也就是说后面的请求需要等到桶中的令牌补齐之后才能继续获取。这段先消费后付款描述的是令牌桶的透支透支额度行为单个请求可以一次性消耗多个甚至桶中全部令牌即允许请求借未来的令牌额度代价是后续请求必须等待直到桶中的令牌被重新补齐后才能继续获取。这在 GuavaRateLimiter的acquire()实现中体现为acquire(n)如果所需令牌数超过当前可用令牌会计算一个等待时长并阻塞当前线程等待时间本质上是为前面透支的令牌付款。漏桶 vs 令牌桶如何选择对比项漏桶算法令牌桶算法输出流量强制恒定速率允许突发受桶容量与令牌积累限制流量控制位置控制流出速率控制令牌生成速率突发流量不支持溢出即丢弃支持短时突发实现复杂度简单略复杂需维护令牌数与上次补充时间典型应用需要严格平滑输出的场景如保护带宽大多数 API/接口限流如 Guava RateLimiter、Nginx limit_req 等令牌桶算法实战基于 Guava RateLimiterJCSprout 仓库的 pom.xml 中引入了 Guava 22.0com.google.guava:guava:22.0而 Guava 的RateLimiter正是令牌桶算法的典型实现。原文档中给出的实战代码位于一个通过 Feign 批量调用远程服务的接口方法内下面保留原代码并补充详细注释Override public BaseResponseUserResVO getUserByFeignBatch(RequestBody UserReqVO userReqVO) { // 调用远程服务 OrderNoReqVO vo new OrderNoReqVO() ; vo.setReqNo(userReqVO.getReqNo()); // 创建一个限流器令牌生成速率为每秒 2 个即平均每秒最多放行 2 个请求 RateLimiter limiter RateLimiter.create(2.0) ; // 批量调用 for (int i 0 ;i 10 ; i){ // 尝试获取一个令牌若当前令牌不足acquire() 会阻塞当前线程直到令牌补齐 // 返回值是本次等待的秒数已耗尽的等待时间可能为 0 double acquire limiter.acquire(); logger.debug(获取令牌成功!,消耗 acquire); BaseResponseOrderNoResVO orderNo orderServiceClient.getOrderNo(vo); logger.debug(远程返回:JSON.toJSONString(orderNo)); } UserRes userRes new UserRes() ; userRes.setUserId(123); userRes.setUserName(张三); userRes.setReqNo(userReqVO.getReqNo()); userRes.setCode(StatusEnum.SUCCESS.getCode()); userRes.setMessage(成功); return userRes ; }关键 API 说明RateLimiter.create(double permitsPerSecond)创建一个令牌桶限流器参数表示每秒补充的令牌数即允许的 QPS。例如create(2.0)表示平均每秒放行 2 个请求。acquire()获取一个令牌。若桶中令牌充足则立即返回若不足则阻塞当前线程直到桶中令牌补齐。返回值为double类型的等待秒数0.0表示无需等待。acquire(int permits)一次性获取多个令牌对应一个请求可以获取多个甚至全部令牌的场景后续请求会因令牌被透支而等待更长时间。tryAcquire()非阻塞版本拿不到令牌立即返回false适合快速失败策略如秒杀场景避免请求排队拖垮系统。需要说明的是该示例中限流器为方法内局部创建在实际项目中应将其提升为static字段或 Spring 单例 Bean 全局共享否则每个请求都会创建新的限流器限流将完全失效。从单机限流到分布式限流原文档在文末列出了两个延伸方向单 JVM 限流与分布式限流。需要强调GuavaRateLimiter是进程内实现限流状态令牌数只存在于当前 JVM 内存中因此只能作用于单机应用在多实例部署的微服务架构下每个实例各自限流总流量会随实例数成倍放大无法达到全局限流的效果。为此JCSprout 仓库收录了分布式限流的完整方案其思路是引入第三方组件Redis统一记录请求次数实现跨实例的全局计数。核心思想Redis Lua 原子计数分布式限流的实现要点如下每次请求时将**当前时间精确到秒**作为 Key 写入 Redis超时时间设置为 2 秒并对该 Key 执行自增当计数达到阈值时返回错误快速失败写入 Redis 的操作用Lua 脚本完成利用 Redis 单线程执行模型的原子性保证并发安全。Lua 脚本如下-- lua 下标从 1 开始 -- 限流 key local key KEYS[1] -- 限流大小 local limit tonumber(ARGV[1]) -- 获取当前流量大小 local curentLimit tonumber(redis.call(get, key) or 0) if curentLimit 1 limit then -- 达到限流大小 返回 return 0; else -- 没有达到阈值 value 1 redis.call(INCRBY, key, 1) redis.call(EXPIRE, key, 2) return curentLimit 1 endJava 侧的调用逻辑public boolean limit() { String key String.valueOf(System.currentTimeMillis() / 1000); Object result null; if (jedis instanceof Jedis) { result ((Jedis) this.jedis).eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit))); } else if (jedis instanceof JedisCluster) { result ((JedisCluster) this.jedis).eval(script, Collections.singletonList(key), Collections.singletonList(String.valueOf(limit))); } else { // throw new RuntimeException(instance is error) ; return false; } if (FAIL_CODE ! (Long) result) { return true; } else { return false; } }其中FAIL_CODE 0脚本返回 0 表示达到阈值返回其他值当前计数表示放行。使用时只需在需要限流的入口处调用redisLimit.limit()并对返回值做判断即可。需要客观说明的是这套 Redis 方案本质上是基于固定时间窗口的计数器限流实现简单直观但时间窗口边界处可能出现双倍流量的突刺并且它并非令牌桶或漏桶那样的平滑限流。文档作者也明确指出这只是利用 Redis 做了一个粗暴的计数器如果想实现类似于上文中的令牌桶算法可以基于 Lua 自行实现。限流组件在秒杀架构中的落地在仓库的秒杀架构实践中限流被用于解决10 个库存、百万请求的经典问题商品库存只有 10 个99% 的请求注定失败与其让海量请求打到数据库不如用分布式限流把并发控制在可控范围内、快速失败最大程度保护数据库。该组件在 v1.0.3 版本中将 Builder 改为接收JedisConnectionFactory并通过RedisToolsConstant.SINGLE/CLUSTER显式指定 Redis 部署形态文档建议使用集群因为限流本身对 Redis 有一定压力同时提供了SpringControllerLimit(errorCode 200)等注解式接入方式。这与MD/Spike.md 中在服务层针对写请求使用请求队列再通过限流算法每秒钟放一部分请求到队列的设计思路一脉相承——先限流再排队最后放行到核心业务。总结限流是保护高并发大流量系统的利器核心诉求是保证可用性优先于吞吐。本文梳理了两条技术脉络算法层漏桶算法强制匀速输出、简单粗暴但无法应对突发流量令牌桶算法以恒定速率放令牌、支持先消费后付款的突发透支能力是绝大多数接口限流场景的首选。落地层单机场景可直接使用 GuavaRateLimiterJCSprout 的 pom.xml 已内置 Guava 22.0分布式场景则需要借助 Redis Lua 实现全局计数并可通过 Builder 模式与注解如SpringControllerLimit降低接入成本。成熟的限流方案还有很多如时间窗口、滑动窗口、信号量等本文从 JCSprout 仓库的限流算法文档出发给出了从原理到单机、再到分布式限流的完整参考路径希望对刚接触限流的朋友提供一些思路。赞分享文档教程后端【免费下载链接】JCSprout‍ Java Core Sprout : basic, concurrent, algorithm项目地址https://gitcode.com/gh_mirrors/jc/JCSprout点击查看免费下载相关推荐京东购物评价如何实现智能自动化3个技术方案彻底解决评价难题京东购物评价如何实现智能自动化3个技术方案彻底解决评价难题 你是否曾经面对京东购物后堆积如山的待评价订单感到头疼每次大促结束几十个商品等待评价手动操作不文档教程后端MaterialColorsApp最佳实践设计师与开发者的高效色彩工作流指南MaterialColorsApp最佳实践设计师与开发者的高效色彩工作流指南 MaterialColorsApp是一款专为Mac用户设计的便捷工具能够快速访Sanic限流算法终极指南如何快速实现令牌桶与漏桶算法保护你的Web应用 Sanic限流算法终极指南如何快速实现令牌桶与漏桶算法保护你的Web应用 在现代Web应用开发中Sanic作为一个高性能的Python异步Web框架后端Web框架上一篇IDM激活脚本技术解析注册表锁定实现试用期无限延长下一篇AUI开发者工具链配置从基础开发环境到完整IDE安装终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Spring MessageConverter 源码解析:消息转换接口设计与 StringMessageConverter 实现原理

Spring MessageConverter 源码解析:消息转换接口设计与 StringMessageConverter 实现原理

文档教程知识库 【免费下载链接】source-code-hunter 😱 从源码层面,剖析挖掘互联网行业主流技术的底层实现原理,为广大开发者 “提升技术深度” 提供便利。目前开放 Spring 全家桶,Mybatis、Netty、Dubbo 框架,及 Red…

2026/9/21 5:22:40 阅读更多 →
如何在无网络环境用 snapDOM 保存截图:3 级存储与关键参数指南

如何在无网络环境用 snapDOM 保存截图:3 级存储与关键参数指南

如何在无网络环境用 snapDOM 保存截图:3 级存储与关键参数指南 【免费下载链接】snapdom High-performance engine for capturing, modifying, and converting DOM elements into any format. 项目地址: https://gitcode.com/GitHub_Trending/sn/snapdom sna…

2026/9/21 6:53:57 阅读更多 →
SeaTunnel Zeta 引擎监控与指标接入指南:Prometheus 采集、指标体系与 Grafana 可视化实战

SeaTunnel Zeta 引擎监控与指标接入指南:Prometheus 采集、指标体系与 Grafana 可视化实战

数据集成ETL大数据批处理流处理变更数据捕获 【免费下载链接】seatunnel SeaTunnel is a multimodal, high-performance, distributed, massive data integration tool. 项目地址: https://gitcode.com/GitHub_Trending/se/seatunnel 点击查看 免费下载 SeaTunnel …

2026/9/21 6:53:21 阅读更多 →

最新新闻

企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范

企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范

企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范 改个需求建站公司拖一周,这种憋屈事谁没经历过?很多老板找企业网站做电脑营销,问得最多的一句话就是“哪家好”。其实,网站好不好用,营销转不转化,核心不在你付了多少钱,而在前端代码写得够不够规范,设计逻辑是否支撑你的业务目标。…

2026/9/21 8:00:00 阅读更多 →
做品管圈网站哪家好?3步避开被黑挂马陷阱

做品管圈网站哪家好?3步避开被黑挂马陷阱

做品管圈网站哪家好?3步避开被黑挂马陷阱 网站上线三天,后台突然多了个奇怪的脚本,页面弹出一堆博彩广告,SEO排名一夜清零。如果你正面临这种“网站被黑挂马不知道怎么办”的噩梦,先别慌着删库重装。很多站长在找做品管圈网站哪家好时,只盯着价格和功能,却忽略了最底层的代码安全与架构选型。今天咱们不聊虚的,…

2026/9/21 7:44:43 阅读更多 →
Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」

Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」

AI 应用前端 【免费下载链接】voyager Enhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用…

2026/9/21 7:41:44 阅读更多 →
gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层

gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层

前端静态站点Web框架 【免费下载链接】gatsby React-based framework with performance, scalability, and security built in. 项目地址: https://gitcode.com/gh_mirrors/ga/gatsby 点击查看 免费下载 本篇技术指南以 gatsby-source-graphql 插件的 CHANGELOG 版…

2026/9/21 7:41:44 阅读更多 →
Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案

Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案

Lightweight Charts v3 到 v4 迁移指南:破坏性变更逐项分析与实战改造方案 【免费下载链接】lightweight-charts Performant financial charts built with HTML5 canvas 项目地址: https://gitcode.com/gh_mirrors/li/lightweight-charts 本指南以 Lightweig…

2026/9/21 7:41:44 阅读更多 →
FoundationDB 存储基准测试上 RAM Disk:mako_storage_bench.sh 在 okteto 开发 Pod 上的 tmpfs 实践指南

FoundationDB 存储基准测试上 RAM Disk:mako_storage_bench.sh 在 okteto 开发 Pod 上的 tmpfs 实践指南

分布式数据库KV存储数据库后端 【免费下载链接】foundationdb FoundationDB - the open source, distributed, transactional key-value store 项目地址: https://gitcode.com/gh_mirrors/fo/foundationdb 点击查看 免费下载 mako_storage_bench.sh 是 FoundationD…

2026/9/21 7:41:44 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →