lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

最近需要对一个接口基于用户进行限流,简单粗暴的固定窗口限流,10s内只允许调3次

一种是直接在JAVA中做逻辑判断

另一种是 通过lua脚本进行实现,故对lua脚本小试牛刀

 

1. 在JAVA里直接实现

 

2.通过lua脚本实现

编写lua脚本,把lua脚本放在resources目录下。

add_fav_limit_rate.lua

local times = redis.call('incr',KEYS[1])
if times == 1 then
    redis.call('expire',KEYS[1], tonumber(ARGV[1]))
end
if times > tonumber(ARGV[2]) then
    return 0
end
return 1

  

JAVA实现代码

    // {"limitTime": 10,"limitUnit": "SECONDS","limitCnt": 3}
    String rule = PropertyConfigurer.getNSString("application", "limit.addFav.rule");
    JSONObject jsonObject = JSONObject.parseObject(rule);
    Integer limitTime = jsonObject.getInteger("limitTime");
    Integer limitCnt = jsonObject.getInteger("limitCnt");

    RedisTemplate redisTemplate =
        RedisTemplateUtil.getRedisTemplateByResourceName(
            RedisConstants.ORCHESTRATOR_SERVICE_RESOURCE);

    String redisKey = RedisConstants.LIMIT_ADDFAV_KEY_PREFIX + userId;

    DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
    redisScript.setResultType(Boolean.class);
    redisScript.setScriptSource(
        new ResourceScriptSource(new ClassPathResource("script/add_fav_limit_rate.lua")));
    List<String> keys = Lists.newArrayList(redisKey);

    Boolean result = (Boolean) redisTemplate.execute(redisScript, keys, limitTime, limitCnt);
    return result;

  

posted on 2021-07-15 10:20  白露~  阅读(327)  评论(0编辑  收藏  举报