RabbitMQ消息的可靠性就是指在消息传递过程中,保证消息被正确传递和处理,确保消息不会丢失、重复或错误地传递。
想要保证消息队列的可靠性,需要知道消息丢失的几种情况。
-
生产者发送消息未到达交换机
-
消息到达交换机,没有正确路由到消息队列
-
消费者收到消息,还没消费完,消费者出现异常错误
-
最极端的情况是MQ宕机,消息队列中的消息没了
如何保证消息不丢失?
需要根据具体的业务场景和需求来选择合适的方法,来保证消息可靠性。
首先需要看消息的重要性?如果是不太重要的消息,例如验证码等信息,丢失了也不会造成太大的影响;如果是重要的消息,就需要相应的处理。
第一种:开始事务。
在RabbitMQ中,可以使用RabbitMQ中提供的事务功能,在传输消息之前,添加事务,如果消息传输的过程中出错了,就会回滚事务,如果没有出现错误,就提交事务。但是,RabbitMQ中的事务机制是同步的,使用事务的话,比较消耗性能,所以一般不用事务功能。
第二种:生产者确认机制。
confirm模式。简单来说就是 把消息正确的放在 exchange交换机,成功了就返回ack确认帧,失败了就返回nack。这个confirm回调函数需要在发送消息前时指定,因为每个业务处理confirm都不一样。
return模式。简单来说就是 在成功到达了交换机后,消息没有正确到达队列,才会触发回调函数。
第三种:消费者确认机制。有三种模式
none模式。只用消息到达消费者那里,就直接返回ack到MQ,MQ接收到ack,就会把队列中相应的消息删除。其缺点就是如果消费者出现异常,就会造成消息丢失,所以这个none模式一般不用。
manual模式。就是自己手动发送ack帧,消费成功时,调用API给MQ返回ack帧;消费失败,调用API给MQ返回nack,并根据业务需求处理消息去向。
auto模式(默认值)。当消息没有出现异常时,返回ack给MQ;如果出现异常,则返回nack,并根据失败策略处理消息。
这个失败策略有三种:
-
RejectAndDontRequeueRecoverer:重试耗尽后,消息不会重新放入队列,而是直接丢弃消息。这个是默认的失败策略
-
ImmediateRequeueMessageRecoverer:重试耗尽后,重新将消息放入队列
-
RepublishMessageRecoverer:重试耗尽后,将失败的消息发布到指定的交换机
第四种:持久化机制
持久化就是防止在系统或者服务器在异常情况下丢失消息
交换机持久化:默认持久化,也可以通过,在创建时,将指定的交换机、队列标识为持久化
队列持久化:默认持久化
消息持久化:默认持久化,也可以在发送消息时,使用Message对象,设置其delivery-mode为persistent,也就是持久化消息