使用
lua := redis.NewScript(script)
args[0] = strconv.Itoa(fillInterval)
args[1] = strconv.FormatInt(time.Now().Unix()*1000, 10)
res, err := lua.Run(context.Background(), utils.Red, []string{"RateLimit"}, args[0], args[1]).Result()
-- 定义返回值res[1]是否触发限流(1限流 0通过)res[2]当前桶中的令牌数
local res={}
res[1]=0
--local curtime=redis.call('time')
local inteval_time=tonumber(ARGV[1]) -- 放入令牌桶的间隔时间
local current_time=tonumber(ARGV[2]) -- 当前时间
local amount=10 -- 一次取几个
local key_expire_time=1000*3600 -- 过期时间
local inflow__per_unit=100 -- 每次放多少
local capacity=1000
local st_key='last_update'
local bucket_amount = 0
-- 上次向桶中投放令牌的时间
local last_time=redis.call('get',st_key)
-- 当前令牌数
local current_value = redis.call('get',KEYS[1])
if(last_time == false or current_value == false) -- 令牌桶也不存在或过期,重新生成令牌桶
then
bucket_amount = capacity - amount;
-- 生成令牌桶
redis.call('set',KEYS[1],bucket_amount,'PX',key_expire_time)
-- 设置投放时间
redis.call('set',st_key,current_time,'PX',key_expire_time)
res[2]=bucket_amount
return res
end
current_value = tonumber(current_value)
last_time=tonumber(last_time)
local past_time=current_time-last_time --当前时间-上次投放的时间
if(past_time<inteval_time)
then
-- 不到放入令牌时间,直接从令牌桶中取走令牌
bucket_amount=current_value-amount
else
-- 需要放入令牌
local cur_times = past_time/inteval_time -- 放几次
cur_times=math.floor(cur_times)
bucket_amount=current_value+cur_times*inflow__per_unit
if (bucket_amount > capacity)
then
bucket_amount = capacity-amount
end
-- 有新投放,更新投放时间
redis.call('set',st_key,current_time,'PX',key_expire_time)
end
res[2]=bucket_amount
-- 触发限流
if(bucket_amount<0)
then
res[1]=1
return res
end
-- 更新令牌桶KV
redis.call('set',KEYS[1],bucket_amount,'PX',key_expire_time)
return res
标签:令牌,--,res,Redis,lua,amount,限流,time,local
From: https://www.cnblogs.com/bruce13/p/17360016.html