rabbitmq数据丢失,分为生产者丢数据,消息队列丢数据和消费者丢数据。

生产者数据丢失

在生产者发送到RabbitMQ时有可能因为网络问题导致投递失败,从而丢失数据。

方案1:rabiitmq事物

采用rabbitmq提供的事务功能

  • 生产者发送数据之前开启rabbitmq事务(channel.txSelect),
  • 然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会收到异常报错,此时就可以回滚事务(channel.txRollback),然后重试发送消息;
  • 如果收到了消息,那么可以提交事务(channel.txCommit)。

但是问题是,rabbitmq事务
一开,会同步阻塞卡住,基本上吞吐量会下来,因为太耗性能了。

方案2:confirm机制
  1. 先将channel设置为confirm模式
  2. 生产者发送一个消息
  3. rabbitmq如果接收到了发送的消息,就会回调生产者本地的接口,通知生产者收到发送的消息
  4. rabbitmq如果在接收消息的时候出现异常,就会回调接口,通知生产者消息接受失败,可再次重发消息

生产者要保证不丢失数据,一般使用confirm机制,异步的模式发送消息后不会阻塞下一个消息的发送,不会造成吞吐量的降低。

rabbitmq数据丢失

如何队列没有对消息持久化,RabbitMQ服务器宕机停止服务,消息丢失。

RabbitMQ自己弄丢数据的情况,需要开启rabbitmq的持久化,在消息写入后持久化到磁盘,设置持久化有两个步骤:

  1. 创建queue的时候将其设置为持久化,保证rabbitmq持久化queue的元数据,但是不会持久化queue里面的数据。
  2. 发送消息的时候将消息的deliveryMode设置为2,即将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘中。

必须要同时设置这两个持久化。且持久化可以跟生产者的confirm机制配合,只有当消息被持久化到磁盘后,才会通知生产者。

消费者数据丢失

消费者从队列中获取消息后,会直接确认签收,假设消费者宕机或者程序出现异常,数据没有正常消费,这种情况就会出现数据丢失。

启用手动确认模式可以解决这个问题:

①自动确认模式

②手动确认模式,如果消费者来不及处理就死掉时,没有响应ack时会重复发送一条信息给其他消费者;如果监听程序处理异常了,且未对异常进行捕获,会一直重复接收消息,然后一直抛异常;如果对异常进行了捕获,但是没有在finally里ack,也会一直重复发送消息(重试机制)。

③不确认模式,acknowledge="none" 不使用确认机制,只要消息发送完成会立即在队列移除,无论客户端异常还是断开,只要发送完就移除,不会重发。