RateLimiter 底层实现是什么?
作者:温安适
来源:https://my.oschina.net/floor/blog/4965200
前言
这篇文章不是Ratelimiter的详细分析,而是概要分析。
令牌桶算法
说到Ratelimiter,必须说令牌桶,其大致逻辑如下:
按图实现
令牌桶的图片在网上随处可见,按照图片实现也很简单。无非是定期添加令牌桶,提供获取令牌的函数。博主实现了以下代码:
importjava.util.concurrent.*;
publicclassMyRateLimiter{
//令牌桶
BlockingQueue TOKEN_BUCKET=newLinkedBlockingDeque(5);
publicstaticvoidmain(String[]args){
MyRateLimitermyRateLimiter=newMyRateLimiter();
myRateLimiter.addTokenFixedRate();
for(inti=0;i<10;i ){<10;i ){
myRateLimiter.acqurie();
System.out.println(第几次执行i:” i 执行时间为:” System.currentTimeMillis());
}
}
/**
*定期添加令牌
*/
publicvoidaddTokenFixedRate(){
ScheduledExecutorServicescheduledExecutorService=Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(()->{
booleansuc=TOKEN_BUCKET.offer(1);
if(!suc){
System.out.println(“令牌桶满了丢弃”;
}
},0,200,TimeUnit.MILLISECONDS);
}
publicvoidacqurie(){
while(TOKEN_BUCKET.poll()==null){};
}
测试结果如下,基本满足要求
Ratelimiter概要实现
一开始,我根据自己的逻辑检查了Guavaratelimiter的源代码。结果发现ratelimiter根本没有收集作为桶。核心是记录下一个令牌的时间和现有令牌的数量,并动态更新它们。
一般逻辑图如下:
按照这张图看核心代码比较容易,核心代码的摘录如下:
@CanIgnoreReturnValue
publicdoubleacquire(intpermits){
longmicrosToWait=reserve(permits);
stopwatch.sleepMicrosUninterruptibly(microsToWait);
return1.0*microsToWait/SECONDS.toMicros(1L);
//Reserve以下代码可以一路向下找到reserveEarliestAvailable
finallongreserveEarliestAvailable(intrequiredPermits,longnowMicros){
resync(nowMicros);
longreturnValue=nextFreeTicketMicros;
//现有令牌可以提供的令牌数
doublestoredPermitsToSpend=min(requiredPermits,this.storedPermits);
////需要刷新的令牌数
doublefreshPermits=requiredPermits-storedPermitsToSpend;
//等待时间=需要刷新的令牌数*固定间隔 等待存储许可证的时间
longwaitMicros=
storedPermitsToWaitTime(this.storedPermits,storedPermitsToSpend)
(long)(freshPermits*stableIntervalMicros);
///下次令牌生产时间=本次令牌生产时间 等待时间
this.nextFreeTicketMicros=LongMath.saturatedAdd(nextFreeTicketMicros,waitMicros);
this.storedPermits-=storedPermitsToSpend;
returnreturnValue;
结论:Ratelimiter根本没有集合作为桶,核心是记录下一个令牌生成的时间和现有令牌的数量,并动态更新它们。
常见问题FAQ
- UU学院资源教程能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 付款了无法下载怎么办?
- 链接地址失效怎么办?