使用redis调用lua脚本的方式对接口进行限流

时间:2025-03-15 08:03:13

java端实现:

   //初始化一个redis可执行的lua
DefaultRedisScript<List> defaultRedisScript = new DefaultRedisScript<List>();
defaultRedisScript.setResultType(List.class);
defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redis_limit.lua"))); List<String> key = new ArrayList<>();//这里虽然使用List集合,但是暂时只存储一个值(Key+时间戳)
List<String> args = Lists.newArrayList("参数值可以是多个");
//这里的StringRedisTemplate需要自己初始化并配置
List<String> ret = new StringRedisTemplate().execute(defaultRedisScript, key, args);//返回也是一个List,就是在lua中的返回值,默认取出第一个即可

lua脚本执行代码:

local key= KEYS[] --获取需要限流接口的key(每秒都会生成一个新的,当然key的过期时间也是1秒)
local limitRqNum= tonumber(ARGV[]) --每秒上限访问个数(获取java调用脚本阶段传入的参数)
local currRqNum= tonumber(redis.call('get',key) or "") --获取当前redis中当前秒内已经存储的请求总数
if currRqNum+ > limitRqNum then --超出流量限制大小的话
return
else --如果没有超出限制请求大小则将redis中记录的请求总数+1,并设置该key
redis.call('INCRBY',key,"") --将请求计数+1
--设置过期时间2秒,这个设置主要是让这个key既能自动失效删除,又能保证在至少1秒内不过期仍旧可以看到当前秒内总请求记录数
redis.call('EXPIRE',key,"")
return
end