最新公告
  • 欢迎来到UU学院,客服Q:5664729我们坚信学习是最好的投资,在这里您可以边学习边赚钱!立即加入我们
  • netlimiter-RateLimiter 的底层实现是啥?

    正文概述 uu网友   2023-10-29   29
    ------------------无法下载或者链接失效请联系页面客服--------------------------

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


    UU学院 » netlimiter-RateLimiter 的底层实现是啥?

    常见问题FAQ

    UU学院资源教程能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    付款了无法下载怎么办?
    部分用户需要先登录才能获取下载地址
    链接地址失效怎么办?
    请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。

    发表评论

    发表评论