令牌桶算法
令牌桶算法(Token Bucket)随着时间流逝,系统会按恒定1/QPS时间间隔(如果QPS=100,则间隔是10ms)往桶里加入Token,如果桶已经满了就不再加了。新请求来临时,会各自拿走一个Token,如果没有Token可拿了就阻塞或者拒绝服务.
20200201001841.png
限流器 rate 原理与上图的令牌桶类似。
限流器 rate 的用法和实现逻辑
官方代码库 github.com/golang/time[1],限流器主要用来限制请求速率,保护服务,防止服务过载。
NewLimiter
func NewLimiter(r Limit, b int) *Limiter
构造限流器,参数说明:
rrb
20200201220059.png
Reserve/ReserveN
rrn
func (lim *Limiter) Reserve() *Reservation
func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation
用法:
// Usage example:
r := lim.ReserveN(time.Now(), 1)
if!r.OK() {
// Not allowed to act! Did you remember to set lim.burst to be > 0 ?
return
}
time.Sleep(r.Delay())
// Act()
实现逻辑
20200201174528.png
Allow/AllowN
•截止到某一时刻,是否可以从桶中获取 N 个令牌。如果可以,消费 n 个 token 并返回 true;否则返回 false。•按照频率限制执行,超过频率限制时丢弃或者跳过
func (lim *Limiter) Allow()
func (lim *Limiter) AllowN(now time.Time, n int) bool
Allow 是 AllowN(time.Now(), 1) 的简写。
实现逻辑
ReserveN
return lim.reserveN(now, n, 0).ok
Wait/WaitN
n
func (lim *Limiter) Wait(ctx context.Context) (err error)
func (lim *Limiter) WaitN(ctx context.Context, n int) (err error)
Wait 是 WaitN(ctx, 1) 的简写。
实现逻辑
20200201215553.png
SetLimit/SetLimitAt
令牌桶限流频率设置。
SetBurst/SetBurstAt
令牌桶容量设置。
引用 限流算法之漏桶算法、令牌桶算法[2]
References
[1][2]