golang 限流器

额,最近工作可能要接一个qps比较高的任务。所以调研一下常用的限流方法:
https://www.infoq.cn/article/Qg2tX8fyw5Vt-f3HH673

似乎最广泛的还是令牌桶算法
https://zhuanlan.zhihu.com/p/89820414

其算法主要思想是:
往一个桶里面放令牌, 判断能够进来的条件就是能否获得令牌。
令牌生成思路就是:

  1. 不停往里放
  2. 获取令牌的时候计算一下可以生成令牌数 = 根据当前时间 - 上次生成时间 / 生成一个令牌的间隔
  3. 如果够的话,更新令牌数并返回
  4. 如果不够的话,等待(或者直接返回错误让客户端重试)

学习一下go标准库里的限流器time/rate是怎么做的,基本逻辑差不多。
但这个是单点的限流,要做分布式的限流还是离不开redis。

集群限流分析:
https://zhuanlan.zhihu.com/p/61661082

笔记:

  1. 并发导致的资源竞争问题
  2. 集群限流由于会面对相比单机更大的流量冲击,所以一般不会进行线程等待,而是直接进行丢弃,因为如果让拿不到令牌的线程进行睡眠,会导致大量的线程堆积,线程持有的资源也不会释放,反而容易拖垮服务器。

思考总结:
单点限流在nginx负载均衡得还不错的情况下,显然是可行的。实现简单,而且可以设置控制中心来实时控制速率(比如从redis-key读取速率, 单key不行就分片)。

用redis控制分布式限流,优点是能够控制总的速度。但是其实压力还是转移到了redis,这也是单点限流的优点可以把压力分摊到每台机器,而且其实并没有太多影响(从golang/org/x的源码看就是一个锁+一些计算)。

所以决定用单点限流试试。
文档:https://www.cyhone.com/articles/usage-of-golang-rate/
关于limit的第二个参数b,理解成容量或最大瞬时并发都可以吧。容量为burst的话,无法在同一时间拿到超过burst。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值