RabbitMQ在手动消费的模式下设置失败重新投递策略

最近在写RabbitMQ的消费者,因为业务需求,希望失败后重试一定次数,超过之后就不处理了,或者放入死信队列。我这里就达到重试次数后就不处理了。本来以为很简单的,问了kimi,按它的方法配置之后,发现报错之后一直重复消费,进入了死循环。

下面是kimi给的"最佳实践"的示例代码:

java 复制代码
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.rabbit.listener.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory myFactory(ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        return factory;
    }
}

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class RabbitMQConsumer {

    @RabbitListener(queues = "your-queue-name", containerFactory = "myFactory")
    public void receiveMessage(final Message message, com.rabbitmq.client.Channel channel) {
        // 消息处理逻辑
        try {
            String payload = new String(message.getBody());
            System.out.println("Received message: " + payload);
            // 业务逻辑处理
            // ...

            // 手动确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            System.out.println("Error processing message: " + e.getMessage());
            try {
                // 拒绝消息并重新入队
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
            } catch (Exception ex) {
                // 如果消息拒绝失败,则关闭通道
                channel.close();
            }
        }
    }
}

问题出在哪里呢?

看起来是很完美的,但是......,还是有漏洞:

这样写是有问题的,会导致失败后消息重新入队,应该是因为重新计算重试次数,如果一直失败,就一直重试,一直清空,那永远不能达到最大次数,导致死循环......

所以,这个地方正确的处理方式是抛异常,

直接throw 一个异常即可。这样就能正确重试了。

这个过程参考了这个博文:rabbitmq消费(失败)重试3次(多次) - 幂次方 - 博客园

总结教训:AI不是万能的,如果按AI的方案得不到结果,有可能是它出错了,毕竟它的方案是没有经过实践检验的。这个时候就会发现原始资料的重要性了。博客还是有它存在的价值的。

相关推荐
CodeWithMe26 分钟前
【Note】《Kafka: The Definitive Guide》 第5章:深入 Kafka 内部结构,理解分布式日志系统的核心奥秘
分布式·kafka
CodeWithMe42 分钟前
【Note】《Kafka: The Definitive Guide》第一章:Meet Kafka
分布式·kafka
CodeWithMe44 分钟前
【Note】《Kafka: The Definitive Guide》 第二章 Installing Kafka:Kafka 安装与运行
分布式·kafka
CodeWithMe5 小时前
【Note】《Kafka: The Definitive Guide》 第8章: Cross-Cluster Data Mirroring
分布式·kafka
Alaia.6 小时前
【kafka 3.9.1】单机版集群部署并配置kafka的SASL认证
分布式·kafka
勤奋的知更鸟7 小时前
Kettle + 大数据实战:从数据采集到分布式处理的完整流程指南
大数据·分布式
Kookoos7 小时前
ABP VNext + Cosmos DB Change Feed:搭建实时数据变更流服务
数据库·分布式·后端·abp vnext·azure cosmos
掘金-我是哪吒21 小时前
分布式微服务系统架构第156集:JavaPlus技术文档平台日更-Java线程池使用指南
java·分布式·微服务·云原生·架构
亲爱的非洲野猪21 小时前
Kafka消息积压的多维度解决方案:超越简单扩容的完整策略
java·分布式·中间件·kafka