给大家推荐一款好用的优快云云服务,新人首购折扣哦,点击下图跳转:

文章目录
RabbitMQ如何防止消息丢失及重复消费
一、消息丢失
如图所示,RabbitMQ丢失消息的情况可以发送在任何一个节点。

1.1、生产者没有成功把消息发送到MQ
丢失的原因 :因为网络传输的不稳定性,当生产者在向MQ发送消息的过程中,MQ没有成功接收到消息,但是生产者却以为MQ成功接收到了消息,不会再次重复发送该消息,从而导致消息的丢失。
解决办法 : 有两个解决办法:事务机制和confirm机制,最常用的是confirm机制(发布确认机制)。
注意:RabbitMQ的事务机制是同步的,很耗型能,会降低RabbitMQ的吞吐量。confirm机制是异步的,生成者发送完一个消息之后,不需要等待RabbitMQ的回调,就可以发送下一个消息,当RabbitMQ成功接收到消息之后会自动异步的回调生产者的一个接口返回成功与否的消息。
两个机制说明如下。
1.1.1、confirm(发布确认)机制
解释:RabbitMQ可以开启 confirm 模式,在生产者那里设置开启 confirm 模式之后,生产者每次写的消息都会分配一个唯一的 id,如果消息成功写入 RabbitMQ 中,RabbitMQ 会给生产者回传一个 ack 消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你的一个 nack 接口,告诉你这个消息接收失败,生产者可以重新发送。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么可以重发。
-
RabbitMQ自带的两个回调:
-
/** * 线程安全有序的一个哈希表,适用于高并发的情况 * 1.轻松的将序号与消息进行关联 * 2.轻松批量删除条目 只要给到序列号 * 3.支持并发访问 */ ConcurrentSkipListMap<Long, String> outstandingConfirms = new ConcurrentSkipListMap<>(); /** * 消息确认成功的回调函数,方法参数:1.消息序列号、2.批量标识,true为批量,false 确认当前序列号消息 */ ConfirmCallback ackCallback = (deliveryTag, multiple) -> { if (multiple) { //2:删除到已经确认的消息 剩下的就是未确认的消息 ConcurrentNavigableMap<Long, String> confirmed = outstandingConfirms.headMap(deliveryTag, true); //删除 confirmed
-

本文详细阐述了RabbitMQ中如何防止消息丢失和重复消费。针对生产者、RabbitMQ服务器和消费者可能出现的问题,提出了确认机制、持久化和消息应答等解决方案。通过开启confirm机制、使用事务、设置消息和队列持久化以及手动ack,确保消息从生产到消费的完整性和一致性。此外,还讨论了如何通过消息唯一性和幂等性来防止重复消费,以保证系统的稳定运行。
最低0.47元/天 解锁文章
1229

被折叠的 条评论
为什么被折叠?



