版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgsxzdl/article/details/89161094
简介
限流算法除了令牌桶还有其他的,但据我所知比较优雅的是令牌桶算法。
令牌桶算法的基本思路是:
假设有一个桶存放令牌,按照固定频率(1/qps)向桶中放入令牌,处理请求时,先从令牌桶中获取令牌,如果获取到直接执行,否则等待,直到获取到所需令牌。
guava 中的 RateLimiter就是基于令牌桶实现的,下面主要描述具体实现,使用的细节不再赘述
细节
这里有几个细节:
- 令牌桶是有容量限制的
- 如何向桶中放入令牌,或者换句话说,如何计算当前桶中令牌的个数
- 如何获取令牌
- 如何处理
- 当令牌不足时,如何处理当前请求和后续请求
下面说一下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
- 使用
storedPermits
存储缓存的令牌 - nextFreeTicketMicros 和 stableIntervalMicros 来计算最近一次获取令牌到现在一共有多少个令牌
TODO