大家好,欢迎来到IT知识分享网。
一、应答模式
RabbitMQ 中的消息应答模式主要包括两种:自动应答(Automatic Acknowledgement)和手动应答(Manual Acknowledgement)。(一般交换机发送消息,RabbitMQ只有在接收到消费者的确认后才会将消息从队列中删除。)在队列发送消息时,首先会先复制一份给消费者,在收到消费者的确认消息后,队列才会将队列中的消息删除。
1、自动应答:
不在乎消费者对消息处理是否成功,都会告诉队列删除消息。如果处理消息失败,实现自动补偿(队列投递过去 重新处理)。
2、手动应答:
- 在手动应答模式下,消费者在接收到消息后并不会立即向RabbitMQ确认消息已处理完毕。消费者需要显式调用
basicAck
方法来确认消息处理完成,RabbitMQ只有在接收到消费者的确认后才会将消息从队列中删除。 - 采用手动应答可以提高消息的可靠性,即使消费者在处理消息过程中出现问题,只要未发送ack确认,RabbitMQ会在重新连接后再次将消息发送给该消费者。
- 如果消费者在处理消息前断开了连接,或者在处理消息期间抛出了未捕获的异常,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提供的消息监听容器,它们之间的区别在于:
- SimpleMessageListenerContainer是基于AMQP协议的,而DirectMessageListenerContainer是基于RabbitMQ的,因此SimpleMessageListenerContainer可以用于其他的AMQP实现,而DirectMessageListenerContainer只能用于RabbitMQ。
- SimpleMessageListenerContainer支持订阅多个队列,可以使用通配符等方式进行配置,而DirectMessageListenerContainer只能订阅一个队列。
- SimpleMessageListenerContainer支持自动声明队列和绑定,而DirectMessageListenerContainer需要手动声明和绑定队列。
- SimpleMessageListenerContainer支持多线程处理消息,而DirectMessageListenerContainer只能单线程处理消息。
因此,如果需要监听多个队列或者使用其他的AMQP实现,可以选择SimpleMessageListenerContainer;如果只需要监听一个队列并且使用RabbitMQ,可以选择DirectMessageListenerContainer。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/144930.html