原文网址:RabbitMQ--消息丢失--原因/解决方案_IT利刃出鞘的博客-CSDN博客
简介
说明
本文介绍RabbitMQ消息丢失的原因以及解决方案(即:如何保证消息不丢失)。
消息在生产者、MQ服务器、消费者都可能丢失消息,本文分析这三处消息丢失的原因以及解决方案。
对于消息队列(MQ)来说,消息丢失/消息重复/消费顺序/消息堆积是比较常见的问题,都属于消息异常,这几个问题比较重要,面试中也会经常问到。
官方文档
Consumer Acknowledgements and Publisher Confirms — RabbitMQ
消息丢失的情景
首先明确一条消息的传送流程:生产者->MQ->消费者
所以这三个节点都可能丢失数据:
- Producer端
- 发送消息过程中出现网络问题:producer以为发送成功,但RabbitMQ server没有收到;
- RabbitMQ server 端
- 接收到消息后由于服务器宕机或重启等原因(消息默认存在内存中)导致消息丢失;
- Consumer端
- Consumer端接收到消息后自动返回ack,但后边处理消息出错,没有完成消息的处理;
生产者丢失消息
消息丢失的情景
生产者将数据发送到RabbitMQ的时候,可能因为网络问题导致数据没到达RabbitMQ Server。
解决方案1:发送方确认机制(推荐,最常用)
详解
生产者将信道设置成confirm(确认)模式,一旦信道进入confirm模式,所有在该信道上面发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,RabbitMQ就会发送一个确认(Basic.Ack)给生产者(包含消息的唯一ID),这就使得生产者知晓消息己经正确到达了目的地了。如果消息和队列是可持久化的,那么确认消息会在消息写入磁盘之后发出。
RabbitMQ回传给生产者的确认消息中的deliveryTag包含了确认消息的序号,此外RabbitMQ也可以设置channel.basicAck方法中的multiple参数,表示这个序号之前的所有消息都已经得到了处理。
如果RabbitMQ因为自身内部错误导致消息丢失,就会发送一条nack(Basic.Nack)命令。
方案
如果生产者收到ack,则不处理。如果收到nack,则重发消息。
上边只是部分内容,为便于维护,本文已迁移到此地址:RabbitMQ消息丢失的原因与解决方案 - 自学精灵