SpringBoot整合RabbitMQ-应答模式

一、应答模式

RabbitMQ 中的消息应答模式主要包括两种:自动应答(Automatic Acknowledgement)和手动应答(Manual Acknowledgement)。(一般交换机发送消息,RabbitMQ只有在接收到消费者的确认后才会将消息从队列中删除。)在队列发送消息时,首先会先复制一份给消费者,在收到消费者的确认消息后,队列才会将队列中的消息删除。

1、自动应答

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

2、手动应答

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

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

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

二、SpringBoot如何实现两种应答。

1、自动应答

在Spring Boot的配置文件application.properties中,对于RabbitMQ监听器,设置自动应答模式(默认就是自动应答)

可以在配置文件中设置自动应答

复制代码
# 自动应答模式
spring.rabbitmq.listener.simple.acknowledge-mode = auto

@Component
public class AutoAcknowledgementConsumer {

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

自动应答的效果:开启自动应答如果出现异常,消费者没有返回确认信息,交换机就会不停发送消息。

会不停的发送请求

2、 手动应答

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

复制代码
# 手动应答模式
spring.rabbitmq.listener.simple.acknowledge-mode = manual

  @RabbitListener(queues = "direct_01")
    public void receiveMessage(Ordering ordering, Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("消费者434接收到消息:" + ordering);
        try {
            // 处理成功手动发送ack确认,yes
            int i = 5 / 0;
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            // 处理失败,可以选择重试或拒绝消息(basicNack或basicReject)
            channel.basicNack(deliveryTag, false, false); // b表示是否批量,b1表示是否并重新入队,选择不重新入队后消息便会丢失
        }
    }

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

复制代码
#应答模式 手动应答需要开发者手动应答
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

四、SimpleMessageListenerContainer和DirectMessageListenerContainer区别

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

  1. SimpleMessageListenerContainer是基于AMQP协议的,而DirectMessageListenerContainer是基于RabbitMQ的,因此SimpleMessageListenerContainer可以用于其他的AMQP实现,而DirectMessageListenerContainer只能用于RabbitMQ。

  2. SimpleMessageListenerContainer支持订阅多个队列,可以使用通配符等方式进行配置,而DirectMessageListenerContainer只能订阅一个队列。

  3. SimpleMessageListenerContainer支持自动声明队列和绑定,而DirectMessageListenerContainer需要手动声明和绑定队列。

  4. SimpleMessageListenerContainer支持多线程处理消息,而DirectMessageListenerContainer只能单线程处理消息。

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

相关推荐
不吃香菜学java6 小时前
Redis的java客户端
java·开发语言·spring boot·redis·缓存
橙露7 小时前
SpringBoot 整合 MinIO:分布式文件存储上传下载
spring boot·分布式·后端
小眼哥8 小时前
SpringBoot整合Vue代码生成exe运行程序以及windows安装包
vue.js·windows·spring boot
shark222222211 小时前
能懂!基于Springboot的用户增删查改(三层设计模式)
spring boot·后端·设计模式
IGAn CTOU12 小时前
王炸级更新!Spring Boot 3.4 正式发布,新特性真香!
java·spring boot·后端
Ssan PRIN12 小时前
深度掌握 RabbitMQ 消息确认(ACK)机制,确保消息万无一失
分布式·rabbitmq
indexsunny14 小时前
互联网大厂Java面试实战:核心技术与微服务架构在电商场景中的应用
java·spring boot·redis·kafka·maven·spring security·microservices
海兰14 小时前
【第3篇-续】多模型多模态项目实现示例(增加OpenAI通用适配)附源代码
java·人工智能·spring boot·alibaba·spring ai
SarL EMEN15 小时前
海康威视摄像头ISUP(原EHOME协议) 摄像头实时预览springboot 版本java实现,并可以在浏览器vue前端播放(附带源码)
java·前端·spring boot
ccice0115 小时前
全面掌握Spring Boot + MyBatis + Maven + MySQL:从开发到部署的后端技术详解
spring boot·maven·mybatis