基于令牌桶算法的限流器RateLimiter分析
RateLimiter限流源码分析
- 主要从以下几个方面进行分析
- RateLimiter工作原理的总体介绍
- RateLimiter的继承关系(基类与子类的关系图)
- 关键属性字段分析
- 核心方法分析(创建--->申请)
- SmoothBursty模式创建RateLimiter的过程(时序图)
主要从以下几个方面进行分析
RateLimiter工作原理的总体介绍
首先RateLimiter是goole 出品的一个基于令牌桶算法的一个组件,其中有两种模式(XSmoothBursty和XSmoothWarmingUp),XSmoothBursty是以恒定速率生成令牌,也就是平滑模式,比如1秒生成5个令牌,那么就是200微秒产生一个令牌。而SmoothWarmingUp代表渐进模式,当速率变大到一定程度后趋于平衡,该模式可以应对突发流量的情况发生。
RateLimiter支持提前消费的概念,比如我每次只能挣5块钱,但是我买东西要花费6块钱,那怎么办呢,我可以通过向老板预支11块钱钱去购买东西,那下一次我还是要买6块钱的东西,那我就得等把上一次的1块钱先还掉才能进行下一次发工资,而挣这一块钱所花费的时间+本身挣5块钱所花费的时间就是我等待的时间,具体数据后面会通过大量的测试进行验证,包括其他情况。
RateLimiter的继承关系(基类与子类的关系图)
RateLimiter是一个抽象类,目前只有一个子类SmoothRateLimiter,而SmoothRateLimiter也是一个抽象类,在SmoothRateLimiter下有两个实现子类,一个是SmoothBursty,一个是SmoothWarmingUp。
关键属性字段分析
RateLimiter中的字段解析
stopwatch | 时间计算器,这里采用的微秒计时,后面用来计算还有多长时间获取令牌时用 |
---|---|
mutexDoNotUseDirectly | 对象锁,设置速率时,线程安全保护,避免临界资源竞争,此处采用的双重锁检查的单列模式来生成的锁 |
SmoothRateLimiter中的字段解析
storedPermits | 剩余的令牌数 |
---|---|
maxPermits | 表示最大允许的令牌数 |
stableIntervalMicros | 每隔多长时间产生一个令牌,采用的时间是微秒 |
– | – |
nextFreeTicketMicros | 表示下一次可以获取令牌的时间,此处是一个相对时间 |
SmoothBursty中的字段分析
·maxBurstSeconds | 表示如果你很久没有请求,但是令牌数不会随着时间推移而增加,而是只缓存1秒的时间的令牌 |
---|---|
SmoothWarmingUp中的字段分析
warmupPeriodMicros | |
---|---|
slope | |
thresholdPermits | |
– | – |
coldFactor |
核心方法分析(创建—>申请)
SmoothBursty模式创建RateLimiter的过程(时序图)
- 在RateLimiter这个抽象类中有创建RateLimiter对象的两个静态方法create(),根据不同的入参获取到具有相应模式的RateLimiter对象,比如创建一个SmoothBursty模式并每秒产生2个令牌的RateLimiter限流器。
//入参必须是大于0的数,不然会抛rate must be positive 异常
RateLimiter rateLimiter = RateLimiter.create(2);
- 进入create方法中,我们发现,做了两件事,第一件事:通过内部类SmoothBursty实例化了一个RateLimiter限流器,入参为:stopwatch(计时器对象)和maxBurstSeconds(最大缓存秒数)第二件事: 设置生成令牌的速率的setRate方法。
static XRateLimiter create(double permitsPerSecond, XRateLimiter.SleepingStopwatch stopwatch) {XRateLimiter rateLimiter = new XSmoothRateLimiter.XSmoothBursty(stopwatch, 1.0 /* maxBurstSeconds */);System.out.println("permitsPerSecond:"+permitsPerSecond);//创建限流器的时候,进行获取令牌的速度设置, 此次有点类似于信号量rateLimiter.setRate(permitsPerSecond);return rateLimiter;}
- 进入setRate方法进行速率设置,在这个方法中,通过锁机制进入doSetRate方法…先调用resync方法进行初始的数据计算,比如:当此刻计时器的数据大于下一次获取令牌的时间(此刻时间为0)的情况下,开始计算storedPermitsd的值和nextFreeTicketMicros的值。
void resync(long nowMicros) {if (nowMicros > nextFreeTicketMicros) {double newPermits = (nowMicros - nextFreeTicketMicros) / coolDownIntervalMicros();storedPermits = min(maxPermits, storedPermits + newPermits);nextFreeTicketMicros = nowMicros;}}
- 接下来设置stableIntervalMicros的值(也就是每多少时间产生一个令牌),并设置最大令牌数maxPermits的值,以及更新storedPermits的值。
//计算出旧的最大许可存储量double oldMaxPermits = this.maxPermits;//获取新的最大的许可存储量(按照秒计算)maxPermits = maxBurstSeconds * permitsPerSecond;//如果旧的最大许可为无限大的情况,那么没有被使用的许可数量也是无限多if (oldMaxPermits == Double.POSITIVE_INFINITY) {storedPermits = maxPermits;//如果不是无限多的话,就重新计算还有多少个许可令牌数} else {storedPermits = (oldMaxPermits == 0.0)? 0.0 : storedPermits * maxPermits / oldMaxPermits;}
基于令牌桶算法的限流器RateLimiter分析相关推荐
- java令牌_基于令牌桶算法的Java限流实现
项目需要使用限流措施,查阅后主要使用令牌桶算法实现,为了更灵活的实现限流,就自己实现了一个简单的基于令牌桶算法的限流实现. 令牌桶算法描述 令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以 ...
- 高并发系统限流-漏桶算法和令牌桶算法
参考: https://www.cnblogs.com/xuwc/p/9123078.html http://www.cnblogs.com/LBSer/p/4083131.html https:// ...
- 流量控制算法——漏桶算法和令牌桶算法
一.写在最前 轰轰烈烈的双十二已经过去小半个月了,程序猿的我坐在办公桌上思考,双十二这么大的访问量,这群电商是怎么扛住的,接口分分钟会变得不可用,并引发连锁反应导致整个系统崩溃.好吃懒做的小编,被可怕 ...
- 限流算法(漏桶算法、令牌桶算法)对比
限流算法(漏桶算法.令牌桶算法) 漏桶算法: 有个桶,比如最大能进2个单位的水(请求),桶底有个洞,每个单位的水都会在桶里待3秒后漏下去. 那么这个桶就可以同时处理2个单位的水. 如果进水太多,同一时 ...
- 使用令牌桶算法解决调用第三方接口限流问题
我们在调用第三方接口时常常会碰到接口限流问题,为了解决这一问题,大家想出了许多方法.我这里介绍一下我的方法,第三方接口限流一般是基于令牌桶算法的,那么我们可以以彼之道还治彼身,使用令牌桶算法实现我方调 ...
- 用令牌桶算法完成API接口限流
这是张富涛的第15篇原创 用令牌桶算法完成API接口限流 本文介绍了"令牌桶算法",和使用lua+redis实现基于令牌桶算法的限流. 1. 限流需求的产生背景 软件开发时偶尔会面 ...
- SpringBoot基于guava集成令牌桶算法
SpringBoot基于guava集成令牌桶算法 一.什么是令牌桶 1.令牌桶 2.功能图 二.Guava 1.简单介绍 2.pom引入 3.限速器 4.浅析重载方法 三.系统应用 1.单个接口应用 ...
- 令牌桶算法PHP简单实现,php 基于redis使用令牌桶算法 计数器 漏桶算法 实现流量控制...
通常在高并发和大流量的情况下,一般限流是必须的.为了保证服务器正常的压力.那我们就聊一下几种限流的算法. 计数器 计数器是一种最常用的一种方法,在一段时间间隔内,处理请求的数量固定的,超的就不做处理. ...
- 令牌桶算法和漏桶算法有什么区别_高并发之限流,到底限的什么鬼 (精品长文)...
你可能知道高并发系统需要限流这个东西,但具体是限制的什么,该如何去做,还是模凌两可.我们接下来系统性的给它归个小类,希望对你有所帮助. google guava中提供了一个限流实现: RateLimi ...
最新文章
- Linux下进程间通信-------管道通信
- odbc 函数序列错误_python时间序列:移动窗口函数前篇
- Path Sum II leetcode java
- 阿里招“AI鉴黄体验官”:日薪1000!网友:钱不钱无所谓,净化互联网人人有责!...
- UA MATH636 信息论9 Berlekamp-Welch算法
- java idle,java – IMAP IDLE库
- PHP连接达梦数据库
- 电脑操作系统维护10条实用建议!
- 机器学习速成课程 | 练习 | Google Development——编程练习:提高神经网络的性能
- ajax中的简单get请求,jquery 之ajax,get,post异步请求简单代码模版(示例代码)
- Flash写操作流程
- fastadmin在html中查询数据,常见问题 · fastadmin 常见问题 · 看云
- python银行卡号识别_EAST+CRNN银行卡号识别,附数据集
- Rational rose安装步骤
- UE_GPU Driven Pipeline Mesh Shader(meshlet)
- 利用阿里云oss实现上传视频和图片功能
- 离散数学——coq学习笔记(一)
- 调查报告:创意行业是否为远程办公做好准备?
- C++关于string类的模拟实现
- 技术分享电商 API 获取商品详情返回值说明(可测试)
热门文章
- futex wait mysql_linux内核级同步机制--futex
- pha-1 android,旧瓶装新酒,旧图新晒——当年新品现远古品 sony 大法 PHA-1
- 移动硬盘数据错误循环冗余检查要如何寻回文件
- easyui treegrid php,Easyui 之 Treegrid 笔记_jquery
- 洛阳地铁一号线无人驾驶_洛阳超级拖拉机I号实现无人驾驶功能
- 2015多校第一场 1005 hdu 5292 Pocket Cube 转魔方
- 《从零进阶!数据分析的统计基础》-2.描述性统计分析
- 学习数码相框1.1.0.0数码相框之系统框架
- pipeline与make_pipeline
- QPM 性能监控组件——总篇