/**
* 防止短信被刷,使用令牌桶限流算法
*/
private void protectMessageService(MemberSendCodeReq memberSendCodeReq) {
String mobile = memberSendCodeReq.getMobile();
String rateKey = "member:sendCode:rate" + mobile;
String lockKey = "member:sendCode:lock" + mobile;
String s = stringRedisTemplate.opsForValue().get(lockKey);
if (!CharSequenceUtil.isBlank(s)) {
log.info("{}请求过于频繁,被拉黑15分钟", mobile);
throw new BusinessException(MEMBER_SEND_CODE_TOO_MANY);
}
RRateLimiter rateLimiter = redissonClient.getRateLimiter(rateKey);
rateLimiter.expire(Instant.now().plusSeconds(3600));
//每60秒产生5个令牌
rateLimiter.trySetRate(RateType.OVERALL, 5, 60, RateIntervalUnit.SECONDS);
//尝试获取一个令牌
boolean acquire = rateLimiter.tryAcquire(1);
if (!acquire) {
//如果一个号码1分钟内请求超过5次就封禁15分钟
stringRedisTemplate.opsForValue().set(lockKey, mobile, 15, TimeUnit.MINUTES);
throw new BusinessException(MEMBER_SEND_CODE_TOO_MANY);
}
}
redisson令牌桶限流对短信服务的运用
于 2023-07-01 10:38:52 首次发布