转!利用redis-rua脚本对短信限流

转自:https://developer.aliyun.com/article/1165600

 

@Autowired
private RedisTemplate<String, Object> redisTemplate;

private static final String LIMIT_LUA = "local num = redis.call('incr', KEYS[1])\n" +
            "if num == 1 then\n" +
            "      redis.call('expire', KEYS[1], ARGV[1])\n" +
            "end\n" +
            "if num > tonumber(ARGV[2]) then\n" +
            "      return 0\n" +
            "end\n" +
            "return 1";

 /**
     * 推送频率限制,seconds内只允许limitNum次
     * @param key key
     * @param seconds 时间 秒
     * @param limitNum 限制次数
     * @return true:限制 false:不限制
     */
    public boolean checkIsLimited(String key, long seconds, long limitNum) {
        try {
            DefaultRedisScript redisScript = new DefaultRedisScript<>(LIMIT_LUA, Long.class);
            Long luaResult = (Long) redisTemplate.execute(redisScript, Collections.singletonList(key), seconds, limitNum);
            log.info("lua脚本执行结果luaResult={}", luaResult);
            return luaResult == 0;
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        return false;
    }


##业务代码:针对单个手机号下发限流
String busyKeyLua ="limit_single_phone:"+phone
boolean limitFlag = checkIsLimited(busyKeyLua, 10L, 2L); 
if (limitFlag) { 
log.warn("短信推送被限制,limitFlag={},busyKeyLua={}", limitFlag, busyKeyLua); 
return new Result(400, "获取验证码过于频繁", null); 
}

  

posted @ 2023-05-19 17:41  乌云de博客  阅读(60)  评论(0编辑  收藏  举报