剖析juju/ratelimit
该项目是一个令牌桶算法实现的限流器, 众所周知, 限流器可以用于控流, 限制访问频率, 保护后端服务.
令牌桶算法实现的限流器可以较好的应对突然流量, 也可以较好的平滑请求
juju/ratelimit
的实现不是像一般的使用后台线程来生成令牌, 前台来取令牌的方案.
juju/ratelimit方案
- 1.通过逻辑时间间隔
tick
, 在每次取令牌的时候计算当前时刻距离上次取令牌的时刻的时间差 - 2.计算出这段时间差应该生成的令牌个数
计算公式是
tb.availableTokens += (tick - tb.latestTick) * tb.quantum
- 3.减掉本次取令牌的个数, 得到剩余的可用令牌个数
- 3.1.判断剩余令牌个数是否大于等于0, 若是就直接返回
- 3.2.若否, 就是本次取的令牌个数大于现有的令牌个数, 所以是欠缺的状态, 这时候有两种处理方式:
- 1.若是调用的阻塞等待函数, 返回等待根据欠缺令牌个数计算出来的等待时刻
- 2.若是调用非阻塞指定超时函数, 返回指定等待时间
- 4.更新保存本次取令牌的时刻
tick
优点
不用维护一个后台线程来生成令牌加入令牌桶中, 只需要在取令牌时计算这段时间需要生成的令牌即可, 实现较简单, 虽然这里使用了锁, 但是可以换为原子值,
cas
无锁实现, 提高性能
缺点
对比后台线程定时生成令牌的方式, 这里会加重取令牌操作的逻辑, 更耗时, 如果是频繁的取令牌, 这种方式就相对多了不必要的判断和计算这段时间所需生成令牌的逻辑
一些优化点
- 1.
nextQuantum
慢速指数逼近quantum
(每个fillInterval
创建的令牌) clock
以接口方式注入, 可自定义计算时钟