如何处理MQ消息丢失的问题?
RabbitMQ丢失消息分为如下几种情况:
-
生产者丢消息:
生产者将数据发送到RabbitMQ的时候,可能在传输过程中因为网络等问题而将数据弄丢了。
-
RabbitMQ自己丢消息:
如果没有开启RabbitMQ的持久化,那么RabbitMQ一旦重启数据就丢了。所以必须开启持久化将消息持久化到磁盘,这样就算RabbitMQ挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢失。除非极其罕见的情况,RabbitMQ还没来得及持久化自己就挂了,这样可能导致一部分数据丢失。
-
消费端丢消息:文章来源:https://www.toymoban.com/news/detail-407935.html
主要是因为消费者消费时,刚消费到还没有处理,结果消费者就挂了,这样你重启之后,RabbitMQ就认为你已经消费过了,然后就丢了数据。
针对上述三种情况,RabbitMQ可以采用如下方式避免消息丢失:
-
生产者丢消息:
- 可以选择使用RabbitMQ提供的事务功能,就是生产者在发送数据之前开启事务,然后发送消息,如果消息没有成功被RabbitMQ接收到,那么生产者会受到异常报错,这时就可以回滚事务,然后尝试重新发送。如果收到了消息,那么就可以提交事务。这种方式有明显的缺点,即RabbitMQ事务开启后,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。
- 可以开启confirm模式。在生产者那里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如果写入了RabbitMQ之中,RabbitMQ会给你回传一个ack消息,告诉你这个消息发送OK了。如果RabbitMQ没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。
事务机制是同步的,你提交了一个事物之后会阻塞住,但是confirm机制是异步的,发送消息之后可以接着发送下一个消息,然后RabbitMQ会回调告知成功与否。 一般在生产者这块避免丢失,都是用confirm机制。
-
RabbitMQ自己丢消息:
设置消息持久化到磁盘,设置持久化有两个步骤:
- 创建queue的时候将其设置为持久化的,这样就可以保证RabbitMQ持久化queue的元数据,但是不会持久化queue里面的数据。
- 发送消息的时候将消息的deliveryMode设置为2,这样消息就会被设为持久化方式,此时RabbitMQ就会将消息持久化到磁盘上。 必须要同时开启这两个才可以。
而且持久化可以跟生产的confirm机制配合起来,只有消息持久化到了磁盘之后,才会通知生产者ack,这样就算是在持久化之前RabbitMQ挂了,数据丢了,生产者收不到ack回调也会进行消息重发。
-
消费端丢消息:
使用RabbitMQ提供的ack机制,首先关闭RabbitMQ的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。文章来源地址https://www.toymoban.com/news/detail-407935.html
到了这里,关于常见面试题---------如何处理MQ消息丢失的问题?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!