go-zero 如何扛住流量冲击(二)
本篇文章承接上一篇go-zero 如何扛住流量冲击(一)。
上一篇介绍的是 go-zero
中滑动窗口限流,本篇介绍另外一个 tokenlimit
,令牌桶限流。
使用
tokenlimit
从整体上令牌桶生产token逻辑如下:
用户配置的平均发送速率为r,则每隔1/r秒一个令牌被加入到桶中;
假设桶中最多可以存放b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃;
当流量以速率v进入,从桶中以速率v取令牌,拿到令牌的流量通过,拿不到令牌流量不通过,执行熔断逻辑;
go-zero
在两类限流器下都采取 lua script
的方式,依赖redis可以做到分布式限流,lua script
同时可以做到对 token 生产读取操作的原子性。
下面来看看 lua script
控制的几个关键属性:
ARGV[1]
rate 每秒生成几个令牌
ARGV[2]
burst 令牌桶最大值
ARGV[3]
now_time「当前时间戳
ARGV[4]
get token nums 开发者需要获取的token数
KEYS[1]
表示资源的tokenkey
KEYS[2]
表示刷新时间的key
上述可以看出 lua script
:只涉及对 token 操作,保证 token 生产合理和读取合理。
函数分析
从上述流程中看出:
有多重保障机制,保证限流一定会完成。
如果
redis limiter
失效,至少在进程内rate limiter
兜底。重试
redis limiter
机制保证尽可能地正常运行。
总结
go-zero
中的 tokenlimit
限流方案适用于瞬时流量冲击,现实请求场景并不以恒定的速率。令牌桶相当预请求,当真实的请求到达不至于瞬间被打垮。当流量冲击到一定程度,则才会按照预定速率进行消费。
但是生产token
上,不能按照当时的流量情况作出动态调整,不够灵活,还可以进行进一步优化。此外可以参考Token bucket WIKI中提到分层令牌桶,根据不同的流量带宽,分至不同排队中。
参考
如果觉得文章不错,欢迎 github 点个star 🤝
同时欢迎大家使用 go-zero
,https://github.com/tal-tech/go-zero
版权声明: 本文为 InfoQ 作者【Kevin Wan】的原创文章。
原文链接:【http://xie.infoq.cn/article/905ddea3c81479e714c6e7b5c】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论