java端實現: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腳本執行代碼:redis
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