JAVA调用

  1. private boolean checkAllowed(String routeId) {
  2. RateLimiterConfig rateLimiterConfig = configMap.get(routeId);
  3. int qps = rateLimiterConfig.getRate();
  4. long now = System.currentTimeMillis();
  5. String key = String.format(RATE_LIMITER_ITEM_KEY_PATTERN, routeId);
  6. Object result = jedisTemplate.evalsha(rateLimiterScriptId, 1, key, String.valueOf(now), String.valueOf(qps));
  7. return Integer.valueOf(result.toString()) > 0;
  8. }

限流lua脚本

  1. local key = KEYS[1]
  2. local curTime = tonumber(ARGV[1])
  3. local qps = tonumber(ARGV[2])
  4. local millis = math.modf(1000 / qps)
  5. local array = redis.call('hmget', key, 'curToken', 'lastTime')
  6. local curToken = array[1]
  7. local lastTime = array[2]
  8. if (type(curToken) ~= 'string') then
  9. curToken = 1
  10. lastTime = curTime
  11. redis.call('hmset', key, 'curToken', curToken, 'lastTime', lastTime)
  12. else
  13. curToken = tonumber(curToken)
  14. lastTime = tonumber(lastTime)
  15. end
  16. local tokenToAdd = math.modf((curTime - lastTime) / millis)
  17. local totalToken = curToken + tokenToAdd
  18. local overload = false
  19. if (totalToken > qps) then
  20. totalToken = qps
  21. overload = true
  22. end
  23. if (totalToken > 0) then
  24. redis.call('hset', key, 'curToken', totalToken - 1)
  25. if (tokenToAdd > 0) then
  26. if (overload) then
  27. lastTime = curTime
  28. else
  29. lastTime = lastTime + tokenToAdd * millis
  30. end
  31. redis.call('hset', key, 'lastTime', lastTime)
  32. end
  33. return 1
  34. else
  35. return 0
  36. end