如何在RabbitMQ中处理验证码发送达到上限后的无限重复消费问题?

想用rabbitmq完成验证码发送业务但是超过设置的上限后就开始无限重复消费!

问过gemini和智谱之类的ai,都是原地改来改去,改了一天现在人已经晕了。

@RabbitHandler
public void sendSignUpCode(Message message,Channel channel, String phoneNumber) throws Exception{
    System.out.println(phoneNumber);
    try {
        //确认60秒内没有重新发送短信
        if (redisUtil.hasKey(RedisKey.signUpCodeSendOneMinLimitKey(phoneNumber))) throw new AccountException(AccountExceptionCode.ACCOUNT_SEND_CODE_LIMTIED);
        //用户一小时内总验证码条数不能超过5条
        if (redisUtil.hasKey(RedisKey.sendCodeCountKey(phoneNumber))){
            int count = Integer.parseInt(redisUtil.getString(RedisKey.sendCodeCountKey(phoneNumber)));
            System.out.println("用户一小时内已发送验证码条数:"+count);
            if (count >= 5) throw new AccountException(AccountExceptionCode.ACCOUNT_SEND_CODE_LIMTIED);
            redisUtil.increment(RedisKey.sendCodeCountKey(phoneNumber));
        }else {
            redisUtil.set(RedisKey.sendCodeCountKey(phoneNumber),"1",60*60);
        }
        //        String code = smsUtil.sendCode(phoneNumber);
        String code = "123456";

       //设置60秒内不能频繁发送短信
       redisUtil.set(RedisKey.signUpCodeSendOneMinLimitKey(phoneNumber),"true",60);


        //保存验证码到redis并设置过期时间为300秒/5分钟
        redisUtil.set(RedisKey.signUpCodeKey(phoneNumber),code,300);
    }finally {
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}
阅读 609
1 个回答

主要更改:
1.异常处理:在 catch 块中添加了 channel.basicReject 方法,确保在异常情况下拒绝消息并不重新入队。
2.消息确认:在 try 块的最后添加了 channel.basicAck 方法,确保消息在成功处理后被确认。

@RabbitHandler
public void sendSignUpCode(Message message, Channel channel, String phoneNumber) throws Exception {
    System.out.println(phoneNumber);
    try {
        // 确认60秒内没有重新发送短信
        if (redisUtil.hasKey(RedisKey.signUpCodeSendOneMinLimitKey(phoneNumber))) {
            throw new AccountException(AccountExceptionCode.ACCOUNT_SEND_CODE_LIMTIED);
        }
        // 用户一小时内总验证码条数不能超过5条
        if (redisUtil.hasKey(RedisKey.sendCodeCountKey(phoneNumber))) {
            int count = Integer.parseInt(redisUtil.getString(RedisKey.sendCodeCountKey(phoneNumber)));
            System.out.println("用户一小时内已发送验证码条数:" + count);
            if (count >= 5) {
                throw new AccountException(AccountExceptionCode.ACCOUNT_SEND_CODE_LIMTIED);
            }
            redisUtil.increment(RedisKey.sendCodeCountKey(phoneNumber));
        } else {
            redisUtil.set(RedisKey.sendCodeCountKey(phoneNumber), "1", 60 * 60);
        }
        // String code = smsUtil.sendCode(phoneNumber);
        String code = "123456";

        // 设置60秒内不能频繁发送短信
        redisUtil.set(RedisKey.signUpCodeSendOneMinLimitKey(phoneNumber), "true", 60);

        // 保存验证码到redis并设置过期时间为300秒/5分钟
        redisUtil.set(RedisKey.signUpCodeKey(phoneNumber), code, 300);

        // 确认消息已被成功消费
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    } catch (Exception e) {
        // 拒绝消息并不重新入队
        channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
        throw e;
    }
}
宣传栏