美文网首页
Guava RateLimiter

Guava RateLimiter

作者: 晚歌歌 | 来源:发表于2020-03-20 16:19 被阅读0次

    概念

    缓存 缓存的目的是提升系统访问速度和增大系统处理容量
    限流 限流的目的是通过对并发请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队、等待或降级等处理
    熔断 依赖的下游服务故障触发自动熔断,避免引发本系统崩溃
    降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开

    限流算法

    • 漏桶算法
      水先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率

    • 令牌桶算法
      对于很多应用场景来说,除了要求能够限制数据的平均传输速率外,还要求允许某种程度的突发传输。这时候漏桶算法可能就不合适了,令牌桶算法更为适合。如图所示,令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务

    RateLimiter

    基于令牌桶算法实现流量限制
    RateLimiter通过限制后面请求的等待时间,容许一定程度的突发流量

    Guava 提供了两种 RateLimiter 的实现:
    SmoothBursty以稳定的速度生成permit
    SmoothWarmingUp是渐进式的生成,最终达到最大值趋于稳定

    原理

    //SmoothRateLimiter.java
    //当前存储令牌数
    double storedPermits;
    //最大存储令牌数
    double maxPermits;
    //添加令牌时间间隔
    double stableIntervalMicros;
    /**
     * 下一次请求可以获取令牌的起始时间
     * 由于RateLimiter允许预消费,上次请求预消费令牌后
     * 下次请求需要等待相应的时间到nextFreeTicketMicros时刻才可以获取令牌
     */
    private long nextFreeTicketMicros = 0L;
    

    RateLimiter的原理就是每次调用acquire时用当前时间和nextFreeTicketMicros进行比较,根据二者的间隔和添加单位令牌的时间间隔stableIntervalMicros来刷新存储令牌数storedPermits。然后acquire会进行休眠,直到nextFreeTicketMicros。

    比如RateLimiter的stableIntervalMicros为500,也就是1秒发两个令牌,storedPermits为0,nextFreeTicketMicros为1553918495748。线程一acquire(2),当前时间为1553918496248,首先resync函数计算,(1553918496248 - 1553918495748)/500 = 1,所以当前可获取令牌数为1,但是由于可以预支付,所以nextFreeTicketMicros= nextFreeTicketMicro + 1 * 500 = 1553918496748。线程一无需等待。

    紧接着,线程二也来acquire(2),首先resync函数发现当前时间早于nextFreeTicketMicros,所以无法增加令牌数,所以需要预支付2个令牌,nextFreeTicketMicros= nextFreeTicketMicro + 2 * 500 = 1553918497748。线程二需要等待1553918496748时刻,也就是线程一获取时计算的nextFreeTicketMicros时刻。同样的,线程三获取令牌时也需要等待到线程二计算的nextFreeTicketMicros时刻。

    相关文章

      网友评论

          本文标题:Guava RateLimiter

          本文链接:https://www.haomeiwen.com/subject/sgejyhtx.html