上篇文章提到固定时间窗口限流无法处理突然请求洪峰情况,本文讲述的令牌桶线路算法则可以比较好的处理此场景。
工作原理
- 单位时间按照一定速率匀速的生产 token 放入桶内,直到达到桶容量上限。
- 处理请求,每次尝试获取一个或多个令牌,如果拿到则处理请求,失败则拒绝请求。
优缺点
优点
可以有效处理瞬间的突发流量,桶内存量 token 即可作为流量缓冲区平滑处理突发流量。
缺点
实现较为复杂
代码实现
core/limit/tokenlimit.go
分布式环境下考虑使用 redis 作为桶和令牌的存储容器,采用 lua 脚本实现整个算法流程。
redis lua 脚本
1 | lua复制代码--每秒生成token数量即token生成速度 |
令牌桶限流器定义
1 | go复制代码type TokenLimiter struct { |
获取令牌
1 | go复制代码func (lim *TokenLimiter) reserveN(now time.Time, n int) bool { |
redis 故障时兜底策略
兜底策略的设计考虑得非常细节
1 | go复制代码//开启redis健康探测 |
本文转载自: 掘金