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根本没有集合作为桶,核心是记录下一个令牌生成的时间和现有令牌的数量,并动态更新它们。

声明:无法下载联系客服Q:5664729声明:以上内容(如有图片或视频亦包括在内)为自媒体平台用户上传并发布,不构成投资建议请自行甄别,本网站不拥有所有权,也不承担相关法律责任。如果您发现有涉嫌版权的内容,请联系我们删除。!