RabbitMQ的自动应答和手动应答,解决重试死循环

RabbitMQ的自动应答和手动应答,解决重试死循环

1.应答模式

RabbitMQ 中的消息应答模式主要包括两种:自动应答(Automatic Acknowledgement)和手动应答(Manual Acknowledgement)。

1、自动应答:

不在乎消费者对消息处理是否成功,都会告诉队列删除消息。如果处理消息失败,实现自动补偿(队列投递过去 重新处理)。

2、手动应答:

1.在手动应答模式下,消费者在接收到消息后并不会立即向RabbitMQ确认消息已处理完毕。消费者需要显式调用basicAck方法来确认消息处理完成,RabbitMQ只有在接收到消费者的确认后才会将消息从队列中删除。

2.采用手动应答可以提高消息的可靠性,即使消费者在处理消息过程中出现问题,只要未发送ack确认,RabbitMQ会在重新连接后再次将消息发送给该消费者。

3.如果消费者在处理消息前断开了连接,或者在处理消息期间抛出了未捕获的异常,RabbitMQ会认为消息未被正确处理,从而重新排队消息,确保消息至少会被消费一次(at least once delivery)。

2.SpringBoot如何实现两种应答。

2.1自动应答

在Spring Boot的配置文件application.properties中,对于RabbitMQ监听器,设置自动应答模式:

#自动应答模式

spring.rabbitmq.listener.simple.acknowledge-mode = auto

java 复制代码
@Component
public class AutoAcknowledgementConsumer {

    @RabbitListener(queues = "yourQueue")
    public void consumeMessage(String message, Message amqpMessage) {
        // 处理消息...
        // 框架会在方法执行完成后自动发送ack确认消息
    }
}

2.2 手动应答

首先,同样在配置文件中启用手动应答模式

#手动应答模式

spring.rabbitmq.listener.simple.acknowledge-mode = manual

java 复制代码
@Component
public class ManualAcknowledgementConsumer implements ChannelAwareMessageListener {

    @Override
    @RabbitListener(queues = "yourQueue")
    public void onMessage(Message message, Channel channel) throws Exception {
        try {
            // 处理消息...
            // 如果处理成功,手动发送ack确认
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 处理失败,可以选择重试或拒绝消息(basicNack或basicReject)
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true); // 并重新入队
        }
    }
}

3.如何解决死循环?重试机制

java 复制代码
#应答模式 手动应答需要开发者手动应答
spring.rabbitmq.listener.simple.acknowledge-mode=AUTO

#批量预抓取数量,提高执行效率
spring.rabbitmq.listener.simple.prefetch = 10
#开启消费者重试机制
spring.rabbitmq.listener.simple.retry.enabled = true
#重试的最大次数
spring.rabbitmq.listener.simple.retry.max-attempts = 6
#重试间隔时间
spring.rabbitmq.listener.simple.retry.initial-interval = 3000
#重试间隔倍数,默认值是1
spring.rabbitmq.listener.simple.retry.multiplier = 2
#最大间隔时间,默认值是10s
spring.rabbitmq.listener.simple.retry.max-interval = 15000

4.SimpleMessageListenerContainer和DirectMessageListenerContainer区别(了解)

SimpleMessageListenerContainer和DirectMessageListenerContainer都是Spring AMQP提供的消息监听容器,它们之间的区别在于:

  • SimpleMessageListenerContainer是基于AMQP协议的,而DirectMessageListenerContainer是基于RabbitMQ的,因此SimpleMessageListenerContainer可以用于其他的AMQP实现,而DirectMessageListenerContainer只能用于RabbitMQ。
  • SimpleMessageListenerContainer支持订阅多个队列,可以使用通配符等方式进行配置,而DirectMessageListenerContainer只能订阅一个队列。
  • SimpleMessageListenerContainer支持自动声明队列和绑定,而DirectMessageListenerContainer需要手动声明和绑定队列。
  • SimpleMessageListenerContainer支持多线程处理消息,而DirectMessageListenerContainer只能单线程处理消息。

因此,如果需要监听多个队列或者使用其他的AMQP实现,可以选择SimpleMessageListenerContainer;如果只需要监听一个队列并且使用RabbitMQ,可以选择DirectMessageListenerContainer。

相关推荐
此时不提桶,更待何时7 小时前
06-17-A-RabbitMQ架构与存储原理详解
rabbitmq
Pniubi12 小时前
分布式锁分类讲解
分布式
nvd1114 小时前
深入剖析:GCP Pub/Sub 与 Apache Kafka 对消息处理延迟与消费者卡死的处理机制异同
分布式·kafka·apache
我不是阵雨15 小时前
分布式事务难题与实战解法全解析
分布式·微服务·架构
song50115 小时前
React Native for OpenHarmony 实战:三方库 react-native-parallax-scroll-view 的鸿蒙化适配指南
分布式·react native·react.js·transformer·harmonyos
做个文艺程序员17 小时前
MQ第03篇:RabbitMQ进阶实战:Topic路由+死信队列+延迟消息,SaaS订单超时取消完整方案
分布式·消息队列·rabbitmq·死信队列·延迟队列
风花一世月17 小时前
[特殊字符] 我把一套分布式消防方案做成了能跑的 3D 沙盘(三架无人机共用一根水带,在线直接玩)
分布式·3d·ai·无人机
我不是阵雨20 小时前
如何拿捏分布式四大模式?
分布式
吴声子夜歌1 天前
Docker入门与实战——实战案例(分布式处理与大数据平台)
大数据·分布式·docker
bksczm1 天前
Redis基础篇之初识分布式
数据库·redis·分布式