蜗牛大师

吴庆龙的学习笔记

导航

基于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

有任何问题欢迎提出。

 

posted on 2022-09-06 15:15  蜗牛大师  阅读(154)  评论(0编辑  收藏  举报