Go 常用的几种 Limiter
三种常用的限流器
- 滑动窗口
- 漏桶限流
- 令牌池
滑动窗口
滑动窗口算法指有一个固定大小的时间窗口T
,设置在这个T
窗口下只能通过M
个请求,并且这个窗口是不断向前移动
计算公式 remaining = M - (resetInSec / T * prevHit + currHit)
resetInSec = exp - ts
- time until end of current window.
- exp: 当前窗口的 end time
- ts: 当前时间
1 |
|
代码逻辑
1 |
|
对于设置 exp
1 |
|
漏桶限流
漏桶限流算法指有一个固定大小的漏桶以固定速率流出水,如果漏桶中没有水就不流出(相当于没有请求),如果流通的水过多就把多余的水丢弃(相当于请求过多)。
实现方法
- 当请求 1 处理结束后, 我们记录下请求 1 的处理完成的时刻, 记为 limiter.last。
- 当请求2到来,如果此刻的时间与 limiter.last 相比并没有达到 perRequest 的间隔大小,那么 sleep
一段时间即可。sleepFor = per - now.Sub(old.last) > 0
1 |
|
最大松弛量 (maxStack)
请求 1 完成后,15ms 后,请求 2 才到来,可以对请求 2 立即处理。请求 2 完成后,5ms 后,请求 3 到来,这个时候距离上次请求还不足
10ms,因此还需要等待 5ms。
1 |
|
令牌池
令牌桶限流算法指有一个固定大小的桶并且按照固定速率向其放入令牌,当桶中令牌个数满了后就拒绝新添加的令牌。当一个请求过来时会去桶里拿一个令牌,如果拿到令牌就说明请求可以通过,如果没有拿到令牌就拒绝请求。
实现方法
使用time.Ticker
来设置规定时间向令牌桶送令牌
速率计算公式 period/max
period 单位时间内,最大可以有多少令牌
参考资料k
Go 常用的几种 Limiter
http://www.bayue.sapce/2022/09/26/limiter/