相比于令牌桶,漏桶更严格,调用方只能严格按照预定的间隔顺序进行消费调用.
uber 在 Github 上开源了一套用于服务限流的 go 语言库 ratelimit, 该组件基于 Leaky Bucket(漏桶) 实现。
ratelimit使用
官方 example
1 | rl := ratelimit.New(100) // per second |
ratelimit 实现
根据传入的limit参数,计算每个请求的间隔limiter.perRequest = time.Second / time.Duration(rate)
根据最近的 limiter.last
最近获取时间,当前时间 now - last = interval 为两次请求的间隔,如果间隔小于 perRequest,那么sleep
perRequest - interval 时间即可.
1 | newState.sleepFor += t.perRequest - now.Sub(oldState.last) |
最大松弛量
在 uber-go 实现的 ratelimit 中,可以把之前间隔比较长的请求的时间,匀给后面的使用,保证每秒请求数 (RPS) 即可。
1 | // 为了防止无限等待达不到限流的效果,引入 maxSlack |
对于需要严格限制请求间隔的情况,ratelimit 提供 WithoutSlack option function,不允许最大松弛量
对于需要使用自定义时钟的情况,提供 WithClock option function,只要实现以下接口即可.
1 | type Clock interface { |