令牌桶算法

Google Guava RateLimiter

1
2
3
4
5
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
  1. 创建令牌:RateLimiter rateLimiter = RateLimiter.create(5); //代表每秒钟生成5个令牌
  2. 消费令牌:rateLimiter.acquire(1); //代表消耗一个令牌
  3. 消费令牌:rateLimiter.tryAcquire(1); //尝试去获取,没有获取到就不等了
  4. 等待时间:double waitTime = rateLimiter.acquire(1); //时间单位为秒

设计思想:

  1. 令牌桶:有最大令牌上限
  2. 令牌生成:以固定速率生成令牌,生成是匀速的
  3. 令牌消费:令牌桶积累了大量的令牌,有大量请求来获取令牌,令牌足够时这些请求都将被通过
  4. 预支消费:如果一次性被消耗的令牌数据量大于已有数量时,RateLimiter的策略是预支给你的,不够的先欠着,灯后续生成了足够的令牌后,再给下一个请求发放令牌

Guava对RateLimiter有两种实现方式:

  1. SmoothBursty:平滑突发限流

  2. SmoothWarmingUp:平滑预热限流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static void main(String[] args) {
//每秒创建5个令牌的平滑突发限流器
RateLimiter burstyLimiter = RateLimiter.create(5);
//每秒创建5个令牌的平滑预热限流器,预热时间2s
RateLimiter warmingUpLimiter = RateLimiter.create(5, 2000, TimeUnit.MILLISECONDS);
DecimalFormat df = new DecimalFormat("0.00");

try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}

System.out.println("稳定限流器:");
IntStream.range(0, 10).forEach(a -> {
double acquire = burstyLimiter.acquire();
System.out.println("第" + a + "此请求等待时间:" + df.format(acquire));
});

System.out.println("预热限流器:");
IntStream.range(0, 10).forEach(a -> {
double acquire = warmingUpLimiter.acquire();
System.out.println("第" + a + "此请求等待时间:" + df.format(acquire));
});
}

三个状态:

  1. 初始(冷却)状态:storedPermits = maxPermits,

    设置令牌速率时初始化 : this.storedPermits = oldMaxPermits == 0.0 ? 0.0 : this.storedPermits * this.maxPermits / oldMaxPermits;

  2. 预热过程:coldFactor * stableIntervalMicros >>> stableIntervalMicros, 耗时就是预热时间,请求等同QPS次数后完成预热

  3. 临界状态:storedPermits <= thresholdPermits, 随着请求获取令牌,storedPermits会相应减少

三个过程:

  1. 趋于稳定过程:storedPermits >> 0,随着请求涌入storedPermits从maxPermits减少到0的过程,就是预热,当storedPermits为0就是稳定状态
  2. 稳定状态:storedPermits = 0,也就是系统已经完成预热,后续获取令牌的频率就是stableIntervalMicros
  3. 冷却过程:storedPermits >> maxPermits,随着时间增加库存令牌会增长到最大令牌数,意味着这时没有请求获取令牌,系统开始冷却下来

令牌桶算法
http://www.zivjie.cn/2023/12/09/算法/限流算法/令牌桶算法/
作者
Francis
发布于
2023年12月9日
许可协议