1. 分布式限流
- Redis + Lua : Redis进行每秒请求计数(Redis计数器功能),达到限流目的。其中,Redis key的设置精确到秒,并且需要对该key设置过期时间为2秒。
-- lua脚本保证redis组合操作的原子性
--lua 下标从 1 开始
-- 限流 key
local key = KEYS[1]
-- 限流大小
local limit = tonumber(ARGV[1])
-- 获取当前流量大小
local curentLimit = tonumber(redis.call('get', key) or "0")
if curentLimit + 1 > limit then
-- 达到限流大小 返回
return 0;
else
-- 没有达到阈值 value + 1
redis.call("INCRBY", key, 1)
redis.call("EXPIRE", key, 2)
return curentLimit + 1
end
- Redis-Cell
Redis 4.0提供了一个限流Redis模块,称为Redis-Cell。该模块使用了漏斗算法,并提供了原子的限流指定。
cl.throttle命令介绍:
> cl.throttle laoqian:reply 15 30 60 1
▲ ▲ ▲ ▲ ▲
| | | | └───── need 1 quota (可选参数,默认值也是1)
| | └──┴─────── 30 operations / 60 seconds 这是漏水速率
| └───────────── 15 capacity 这是漏斗容量
└─────────────────── key laoqian...
// 执行cr.throttle命令返回结果含义如下所示
> cl.throttle laoqian:reply 15 30 60
1) (integer) 0 # 0 表示允许,1表示拒绝
2) (integer) 15 # 漏斗容量capacity
3) (integer) 14 # 漏斗剩余空间left_quota
4) (integer) -1 # 如果拒绝了,需要多长时间后再试(漏斗有空间了,单位秒)
5) (integer) 2 # 多长时间后,漏斗完全空出来(left_quota==capacity,单位秒)
其中,上述参数代表的含义是每60s最多允许30次操作,且初始时刻允许15个并发操作。在该命令执行被拒绝时,可以采用同步阻塞或异步定时方式进行重试。
网友评论