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

浙公网安备 33010602011771号