RateLimiter限流 - 令牌桶

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgsxzdl/article/details/89161094

简介

限流算法除了令牌桶还有其他的,但据我所知比较优雅的是令牌桶算法。
令牌桶算法的基本思路是:

假设有一个桶存放令牌,按照固定频率(1/qps)向桶中放入令牌,处理请求时,先从令牌桶中获取令牌,如果获取到直接执行,否则等待,直到获取到所需令牌。

guava 中的 RateLimiter就是基于令牌桶实现的,下面主要描述具体实现,使用的细节不再赘述

细节

这里有几个细节:

  1. 令牌桶是有容量限制的
  2. 如何向桶中放入令牌,或者换句话说,如何计算当前桶中令牌的个数
  3. 如何获取令牌
  4. 如何处理
  5. 当令牌不足时,如何处理当前请求和后续请求

下面说一下RateLimiter对于上面细节的处理

代码中具体类

RateLimiter是一个抽象类,它有两个私有静态子类:
Bursty:突发无预热
WarmingUp:有预热

下面以Bursty来描述具体的细节,WarmingUp后续再研究

令牌桶的容量

  /**
   * The maximum number of stored permits.
   */
  double maxPermits;

这个值表示存储的最大令牌数
对于Bursty来说:

maxPermits = maxBurstSeconds * permitsPerSecond;

使用RateLimiter.create 创建时,maxBurstSeconds = 1,也就是maxPermits = permitsPerSecond

如何放入令牌

  /**
   * The currently stored permits.
   */
  double storedPermits;
  /**
   * The interval between two unit requests, at our stable rate. E.g., a stable rate of 5 permits
   * per second has a stable interval of 200ms.
   */
  volatile double stableIntervalMicros;
  /**
   * The time when the next request (no matter its size) will be granted. After granting a request,
   * this is pushed further in the future. Large requests push this further than small requests.
   */
  private long nextFreeTicketMicros = 0L; // could be either in the past or future
  1. 使用storedPermits 存储缓存的令牌
  2. nextFreeTicketMicros 和 stableIntervalMicros 来计算最近一次获取令牌到现在一共有多少个令牌

TODO

猜你喜欢

转载自blog.csdn.net/zgsxzdl/article/details/89161094