java限流

复制代码

@Component
public class LimiterUtil {
@Resource
private RedisTemplate<String, String> redisTemplate;

/**
 * 固定窗口限流算法
 *
 * @return true 限流  false 放行
 */
public boolean fixedWindow(String key, int count) {
    long countCache = redisTemplate.opsForValue().increment(key);
    return countCache > count;
}

/**
 * intervalTime 时间内 最多只能访问5次
 *
 * @param key          缓存key
 * @param currentTime  当前时间  new Date().getTime();
 * @param intervalTime 有效期
 * @param count        限流次数
 * @return true 限流 false 放行
 */
public boolean slidingWindow(String key, Long currentTime, Long intervalTime, int count) {
    //发送次数+1
    redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), currentTime);
    // intervalTime是限流的时间
    int countCache = Objects.requireNonNull(redisTemplate.opsForZSet().rangeByScore(key, currentTime - intervalTime, currentTime)).size();
    return countCache > count; 
}
}
复制代码
复制代码

/**
*发送短信单位时间内次数限制采用的是slidingWindow()方法的参数。
*/
public
CommonResult<Boolean> sendCode(String phone, String codeCachePre, Integer msgType) { if (StringUtil.isEmpty(phone)) { return CommonResult.failed(ResultCode.VALIDATE_FAILED); } ParamValidate.isNull(phone, "phone参数为空"); //同一个手机号码 发送次数限流 //同一个手机号每秒 最多只能发5次 boolean limit = limiterUtil.slidingWindow(RedisConstantPre.MESSAGE_LIMIT_KEY_PRE + phone, (new Date()).getTime(), 60000L, 5); if (limit) { return CommonResult.failed(ResultCode.SEND_MESSAGE_LIMIT); } CommonResult<MessageTemplateDto> commonResult = messageTemplateFeignClient.queryByMessageType(msgType); if (commonResult.getCode() != ResultCode.SUCCESS.getCode()) { log.error("短信模板不存在,tye={}", msgType); return CommonResult.failed(ResultCode.VALIDATE_FAILED); } MessageTemplateDto messageTemplateDto = commonResult.getData(); //生成随机验证码 String code = RandomUtil.randomNumbers(6); log.info("登录发送验证码:{}", code); //发送验证码 String content = messageTemplateDto.getContent(); //验证码占位符 String newContent = content.replace(messageTemplateDto.getContentParam(), code); //调用MQ 异步发送短信验证码 phoneMessageProducer.sendPhoneMessage(phone, newContent); //存到redis中 设置有效期 60秒 //60秒后需要重现发送 redisConfig.set(codeCachePre + phone, code, 60); return CommonResult.success(Boolean.TRUE); }
复制代码

 

posted on   五官一体即忢  阅读(24)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示