今天在写用于限流的漏桶算法,使用了 channel 来模拟“桶”。大致方法是这样:
- 定时从 channel 中读出数据(模拟桶漏水)
- 收到请求时如果 channel 没有满,就写入
- 收到请求时如果 channel 满了,就抛弃请求并返回“超出 QPS 限制”(不要阻塞)
众所周知,channel 是阻塞的,但有办法模拟出第 3 点的要求,代码如下:
1 | var bucket = make(chan struct{}) |
运行结果如下(或点击这里修改运行程序)
1 | bucket is full |
关键在于 select 中的 default,当其他分支阻塞时会执行 default 分支,这样就实现了“非阻塞 channel”的需求。