美文网首页
RateLimiter源码

RateLimiter源码

作者: 技术灭霸 | 来源:发表于2021-11-05 01:21 被阅读0次

Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法实现流量限制,使用十分方便。

@Test
fun rateLimiterTest() {
    val rateLimiter = RateLimiter.create(0.5)

    arrayOf(1,6,2).forEach {
        println("${System.currentTimeMillis()} acq $it:\twait ${rateLimiter.acquire(it)}s")
    }
}

以上示例,创建一个RateLimiter,指定每秒放0.5个令牌(2秒放1个令牌),其输出见下

1516166482561 acq 1: wait 0.0s
1516166482563 acq 6: wait 1.997664s
1516166484569 acq 2: wait 11.991958s

从输出结果可以看出,RateLimiter具有预消费的能力:

  • acq 1时并没有任何等待直接预消费了1个令牌
  • acq 6时,由于之前预消费了1个令牌,故而等待了2秒,之后又预消费了6个令牌
  • acq 2时同理,由于之前预消费了6个令牌,故而等待了12秒

从另一方面讲,RateLimiter通过限制后面请求的等待时间,来支持一定程度的突发请求(预消费)

但是某些情况下并不需要这种突发请求处理能力,如某IM厂商提供消息推送接口,但推送接口有严格的频率限制(600次/30秒),在调用该IM厂商推送接口时便不能预消费,否则,则可能出现推送频率超出限制而失败。该情况的处理会在其他博文中介绍。

源码解读

Guava有两种限流模式,一种为稳定模式(SmoothBursty:令牌生成速度恒定),一种为渐进模式(SmoothWarmingUp:令牌生成速度缓慢提升直到维持在一个稳定值)
两种模式实现思路类似,主要区别在等待时间的计算上,本篇重点介绍SmoothBursty

根据令牌桶算法,桶中的令牌是持续生成存放的,有请求时需要先从桶中拿到令牌才能开始执行,谁来持续生成令牌存放呢?

一种解法是,开启一个定时任务,由定时任务持续生成令牌。这样的问题在于会极大的消耗系统资源,如,某接口需要分别对每个用户做访问频率限制,假设系统中存在6W用户,则至多需要开启6W个定时任务来维持每个桶中的令牌数,这样的开销是巨大的。

另一种解法则是延迟计算,如上resync函数。该函数会在每次获取令牌之前调用,其实现思路为,若当前时间晚于nextFreeTicketMicros,则计算该段时间内可以生成多少令牌,将生成的令牌加入令牌桶中并更新数据。这样一来,只需要在获取令牌时计算一次即可。

相关文章

  • c++实现令牌桶

    1.RateLimiter.h 2.RateLimiter.cpp 3.编译源码 4.运行及其结果

  • RateLimiter源码

    Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法实现流量限制,使用十分方...

  • RateLimiter源码解析

    计数器限流 最原始的代码 但是计数器限流无法对相邻两秒都是高qps进行限流,比如1:29:29.999有100qp...

  • guava 限流RateLimiter 初探(一)

    Guava RateLimiter Guava RateLimiter原理 Guava RateLimiter基于...

  • Guava RateLimiter源码解析

    前言 在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理...

  • RateLimiter源码分析2

    一、前言 上一篇结尾的时候我提了两个问题,这一次主要针对这两个问题进行思考和讨论。 问题1这里的returnVal...

  • RateLimiter-源码分析

    一、前言 在分布式系统中,实现高可用有三大利器: 限流 降级 熔断我们先对限流来进行一个分析。 二、限流的实现 业...

  • Guava RateLimiter限流源码解析

    RateLimiter的设计思想 RateLimiter最大的特点是它可以以一个稳定的速率让线程通过。当线程过多的...

  • Java并发 -- Guava RateLimiter

    // 限流器流速:2请求/秒RateLimiter limiter = RateLimiter.create(2....

  • Guava之RateLimiter的设计

    Guava源码中很详尽的解释了RateLimiter的概念。 从概念上看,限流器以配置速率释放允许的请求(perm...

网友评论

      本文标题:RateLimiter源码

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