基于Redis的token限流实现
造轮子的过程也是学习的过程。
如果公司的 Redis 不支持发布订阅指令的话,是没法用 Redisson 的,因为 Redisson 的大部分功能都依赖于 Redis 的发布订阅指令。
这是完整实现的代码仓库:https://gitee.com/wu0916/redis-rate-limiter
下面这段 lua 代码是基于 Redis 的 RateLimiter 的实现:
local max=tonumber(ARGV[1]) -- 单位时间内的最大令牌数
local interval=tonumber(ARGV[2]) -- 生成一个令牌的间隔毫秒数
local align=tonumber(ARGV[3]) -- 当前时间戳(对齐之后的时间戳)
align=align-(align%interval) -- 对齐当前时间戳
local latest=redis.call('HGET',KEYS[1],'latest') -- 获取最后一次成功获取令牌的时间戳
if latest then
local remain=tonumber(redis.call('HGET',KEYS[1],'remain'))
local diff=align-tonumber(latest)
if diff>1000 then
remain=1
elseif diff>=interval then
remain=math.min((math.floor(diff/interval)+remain),max)
end
if remain<=0 then
return 0
else
redis.call('HSET',KEYS[1],'remain',remain-1,'latest',align)
return 1
end
else -- 如果首次获取,直接返回成功,并设置时间为对齐时间
redis.call('HSET',KEYS[1],'remain',0,'latest',align)
return 1
end
有任何问题欢迎提出。
------------------------------我是博客签名------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------
浙公网安备 33010602011771号