0


【RabbitMQ】消息丢失及解决方案

废话少说,我们快速开始!!!

什么是消息丢失?

    通俗点讲就是消费从生产者生成到消费者消费这个过程中,消息没有真正的被消费者处理。它可能在传递过程中丢失了,消费者根本没有接收到;或者是消费者在处理消息时出现异常了,消息没有被真正的处理完毕,这都属于消息丢失的范畴。

RabbitMQ 消息丢失的三种情况

  1. 生产端消息丢失 原因:消息在发送到MQ的过程中,由于网络等原因导致消息没有发送到MQ,或者MQ没有收到消息。 解决方案: 1.1 开启RabbitMQ事务机制,生产者发送数据之前开启 RabbitMQ 事务channel.txSelect,然后发送消 息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit,类似我们数据库数据库事务机制。 1.2 开启RabbitMQ有confirm模式,生产者实例可以在发送消息前可以开启confirm模式,打开confirm模式后,每个被投递到这个channel的消息都会分配一个唯一ID标识,当消息写入RabbitMQ之后,RabbitMQ会回传一个ack消息给生产者,ack消息包含消息的唯一ID标识,这样生产者就能知道消息被准确收到;如果RabbitMQ因为自身内部错误导致消息丢失,就会回传一个nack消息给生产者,这样就会调用一个我们处理nack消息的回调函数,在这个回调函数中我们可以写一些消息重发逻辑。
网络异常导致消息没有发送出去可以进行重试处理,如果已经到MQ,因MQ自身原因导致消息无法正常消费,可以根据NACK回调进行重试处理
`try{
    producer.send(message);}catch(NetworkException e){// 处理网络异常,进行重试retry(message);}`

事务机制和 confirm 机制优劣:
事务机制是同步的,提交一个事务之后会阻塞,吞吐量会下来,耗性能。
confirm 机制是异步的,流程不会阻塞,吞吐量较高,性能较好。

  1. MQ丢失消息 原因:消息一般都是存储在内存中的,当消息到达RabbitMQ后,RabbitMQ因为一些原因宕机了,内存中的数据肯定不复存在,导致消息丢失。 解决方案:无论是生产端也好还是消费端也好,在声明queue(队列)以及exchange(交换机)的时候将它们设置为可持久化的。除此之外,在生产者发送消息时,将消息的deliveryMode设置成持久化的,这样RabbitMQ就会将消息持久化到磁盘上,即使MQ宕机了,重启后也能从磁盘上恢复消息数据。这种方案一般是配合生产者的confirm模式共同使用:只有当消息被持久化到磁盘后,MQ才会发送ack消息通知生产端。
  2. 消费端丢失消息 原因:消费端在处理消息的过程中出现异常,消息没有得到正常、恰当的处理,导致消息丢失。 解决方案:默认的消息确认机制是消费者一收到消息,就会回一个ack消息给MQ,并且MQ一收到消费端的ack消息,就会将消息从内存或磁盘中移除。我们可以在消费者订阅队列时,关闭autoAck,关闭后消费端不会一收到消息会回ack,而是在业务处理完后,需要手动调用方法发送ack消息给MQ:channel.basicAck(),MQ也会一直等待直到消费端调用basicAck,回复确认消息后,才会将消息从内存或磁盘中移除。

具体可以参考:https://hiddenpps.blog.csdn.net/article/details/55515234

标签: rabbitmq

本文转载自: https://blog.csdn.net/qq_46226259/article/details/136994775
版权归原作者 qq_46226259 所有, 如有侵权,请联系我们删除。

“【RabbitMQ】消息丢失及解决方案”的评论:

还没有评论