【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

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值