
实现的思路是:每次请求来了,先补充令牌(+=距离上次获取令牌的时间间隔 * 补充令牌速率),再获取令牌(-=获取令牌数量)。
现在疑惑的是:在实际应用中,最大令牌桶容量 max_tokens、初始令牌桶容量 cur_tokens 和补充令牌速率 fill_rate 设置应该参考什么标准?
核心两个函数的代码贴在下面,非常感谢大家!
def _acquire(self, tokens): if tokens <= self.replenish(): # 先补充令牌 self.cur_tokens -= tokens # 再获取令牌 return True return False def _replenish(self): if self.cur_tokens < self.max_tokens: now = time() del_tokens = self._fill_rate * (now - self._last_time) self.cur_tokens = min(self.max_tokens, self.cur_tokens + del_tokens) self._last_time = now return self.cur_tokens 1 janxin 2020-08-04 15:36:39 +08:00 这个速度标准应该看具体业务进行吧,比如业务压力承受能力 也有一部分纯业务层面:更新速率本来就慢,不希望 /没必要反复获取 |
2 LotteWong OP @janxin 我的想法是,补充令牌速率 fill_rate 对应 qps,最大令牌桶容量 max_tokens 对应支持的最大用户并发数,初始令牌桶容量 cur_tokens 就根据启动的平均用户并发数来定,不知道这样理解对不对 |
3 pwli 2020-08-04 15:50:08 +08:00 max_tokens 对应最大突发请求吧 |
4 anzu 2020-08-04 15:57:58 +08:00 不加锁吗 |
5 wangyanrui 2020-08-04 16:01:18 +08:00 具体业务,另外这个东西最好支持动态修改~ |
6 LotteWong OP |
7 wangyanrui 2020-08-04 16:27:36 +08:00 @LotteWong 比如配置中心啊,数据库定时刷新啊,配置文件定时刷新啊。都可以的 |
8 xuanbg 2020-08-04 16:47:25 +08:00 楼主可以搞一个接口配置表,然后从接口配置表中读取限流参数,还可以从配置表读取是否需要鉴权等等…… |
9 LotteWong OP |
10 joApioVVx4M4X6Rf 2020-08-04 20:33:21 +08:00 求开源,想学习楼主的代码 |
11 hakim 2020-08-04 20:38:39 +08:00 我记得有个小技巧,就是第一次请求放行,下一次请求需要等待的时间=第一次请求所需令牌数 /生成速度 |
12 realpg PRO 没啥可参考的,要根据业务模型去设置。 看你的业务 QOS 的目的是什么,然后结合用户包形态。 比如常见的,让用户舒服,又不会长期干扰现网的 结合用户协议的波峰形状 对用户影响最小又不干扰现网即可。 实际生产环境,对于共享带宽业务,甚至有 burst 极大的 |
13 LotteWong OP @v2exblog 我也是参考 github 的: https://github.com/titan-web/rate-limit @hakim 这个好像是 guava 允许预支付令牌的思路,我研究下 @realpg 主要想做的是限制不同用户对中间层的单秒请求次数上限,感觉这里面还要考虑中间层不同接口的耗时也有差异,现在暂时也做不了压测,只能留出配置项到时候看情况改了 |