工作生活

令牌桶限流 - RateLimiter

2019-07-02  本文已影响0人  沐兮_d64c

1,RateLimiter类层次结构

1)SmoothRateLimiter平滑限流


image.png

2)SmoothBursty 平滑支持突发


image.png
3)SmoothWarmingUp 平滑预热限流
image.png

2,RateLimiter基类

1)成员计时器、锁


image.png

2)模板方法set、get速率


image.png

3,SmoothRateLimiter抽象类

1)令牌存储
nextFreeTicketMicros:下次请求需要等到nextFreeTicketMicros时刻才可以获取令牌。如果线程1与消费permits多,则nextFreeTicketMicros越往后。

image.png
2)resync控制方法
image.png

4,令牌生成与获取

1)令牌生成
定时任务生成令牌系统资源消耗极大,如跟对每个user限流,则需要开启n个定时任务。(不采取)
惰性结算生成令牌根据nowMicros > nextFreeTicketMicros作比较,如果大于说明不需要等待,补充nowMicros - nextFreeTicketMicros 之间生成的令牌。 如果小于,则需要等待。
2)令牌获取
acquire方法:计算获取permits个令牌需要等待的时间 ->底层调用Thread.sleep休眠 -> 返回waitTime休眠时间。

image.png
基于synchronized:实现同步
image.png
image.png
reserveEarliestAvailable模板方法,SmoothRateLimiter实现:计算下一次请求需要等待的时间,nextFreeTicketMicros。
增加storedPermits令牌:resync:增加从nowMicros - 原nextFreeTicketMicros之间可以产生的令牌数。
image.png
基于当前时间,更新storedPermits和nextFreeTicketMicros
image.png

5,SmoothBursty 平滑支持突发

1)创建
默认可以存储maxBurstSeconds秒未使用的permits,避免不必要的停顿。
创建SmoothBursty时,可以指定maxBurstSeconds,用于计算maxPermits。

image.png
2)类结构
image.png
3)SmoothBursty预消费(令牌不足下次调用来买单)
如图令牌桶无令牌,第一次acquire未阻塞。第二次阻塞了3s,因为预先获取了3个permits,qps为1。
image.png

6,SmoothWarmingUp:平滑预热限流

1)创建
permitsPerSecond:每秒的令牌数
warmupPeriod:预热期(before reaching its stable (maximum) rate)
unit:预热期,时间单位

image.png
coldFactor:冷启动系数,默认3.0
cold interval:coldIntervalMicros = stableIntervalMicros * coldFactor;默认是stable interval的3倍。
image.png
2)thresholdPermits,系统 stable 阶段和 cold 阶段的临界点
slope代表梯形的斜率
image.png
3)平滑预热图(从右往左看)
thresholdPermits是一个拐点。
当令牌数小于thresholdPermits时,生成令牌的间隔时间稳定在stable interval
当令牌数大于thresholdPermits时,生成令牌的间隔时间以一个固定的速率发生变化。
image.png
4)storedPermitsToWaitTime方法
SmoothBursty:storedPermitsToWaitTime方法,直接返回0。SmoothWarmingUp:storedPermitsToWaitTime方法根据令牌数与thresholdPermits的关系来计算等待的时间。`
image.png

7,tryAcquire非阻塞式限流、降级

1)使用tryAcquire达到非阻塞式限流。


image.png

2)tryAcquire可以指定超时时间。


image.png
上一篇下一篇

猜你喜欢

热点阅读