JAVA调用
private boolean checkAllowed(String routeId) { RateLimiterConfig rateLimiterConfig = configMap.get(routeId); int qps = rateLimiterConfig.getRate(); long now = System.currentTimeMillis(); String key = String.format(RATE_LIMITER_ITEM_KEY_PATTERN, routeId); Object result = jedisTemplate.evalsha(rateLimiterScriptId, 1, key, String.valueOf(now), String.valueOf(qps)); return Integer.valueOf(result.toString()) > 0;}
限流lua脚本
local key = KEYS[1]local curTime = tonumber(ARGV[1])local qps = tonumber(ARGV[2])local millis = math.modf(1000 / qps)local array = redis.call('hmget', key, 'curToken', 'lastTime')local curToken = array[1]local lastTime = array[2]if (type(curToken) ~= 'string') then curToken = 1 lastTime = curTime redis.call('hmset', key, 'curToken', curToken, 'lastTime', lastTime)else curToken = tonumber(curToken) lastTime = tonumber(lastTime)endlocal tokenToAdd = math.modf((curTime - lastTime) / millis)local totalToken = curToken + tokenToAddlocal overload = falseif (totalToken > qps) then totalToken = qps overload = trueendif (totalToken > 0) then redis.call('hset', key, 'curToken', totalToken - 1) if (tokenToAdd > 0) then if (overload) then lastTime = curTime else lastTime = lastTime + tokenToAdd * millis end redis.call('hset', key, 'lastTime', lastTime) end return 1else return 0end