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

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

 

posted @ 2019-08-08 15:47  soft.push("zzq")  Views(1105)  Comments(0Edit  收藏  举报