转!利用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); }