定制设计RabbitMQ如何保证消息不丢失

定制设计首先我们来讨论一下MQ定制设计数据丢失的场景

1.定制设计生产者丢失消息
定制设计第一种情况就是生产者丢失消息,定制设计生产者生产了消息在传定制设计递的过程中把消息弄丢了

2.MQ定制设计队列丢失了消息
重启后,定制设计之前的数据丢失了。定制设计所以必须开启持久化将定制设计消息持久化到磁盘,这样就算rabbitmq挂了,定制设计恢复之后会自动读取之前存储的数据,一般数据不会丢失。除非极其罕见的情况,rabbitmq还没来得及持久化自己就挂了,这样可能导致一部分数据丢失。

3.消费者丢失消息
消费者消费时,刚拿到消息,还没有处理,结果消费者就挂了,消费者重启之后,rabbitmq就认为你已经消费过了,然后就丢了数据。

如何防止消息的丢失呢?

1:生产者丢失消息
第一种解决办法我们可以开启事务功能,
可以选择使用rabbitmq提供的事物功能,就是生产者在发送数据之前开启事物,然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会受到异常报错,这时就可以回滚事物,然后尝试重新发送;如果收到了消息,那么就可以提交事物。

  channel.txSelect();//开启事物  try{  }catch(Exection e){      channel.txRollback()//回滚事物      //重新提交  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

缺点:rabbitmq事物一旦开启,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。这有点违背我们的初衷了。

第二种办法是开启confirm模式,
在生产者开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如何写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。

    //开启confirm    channel.confirm();    //发送成功回调    public void ack(String messageId){          }    // 发送失败回调    public void nack(String messageId){        //重发该消息    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

事务机制是同步的,你提交了一个事物之后会阻塞住,但是confirm机制是异步的,发送消息之后可以接着发送下一个消息,然后rabbitmq会回调告知成功与否。
一般在生产者这块避免丢失,都是用confirm机制。

2.MQ丢失了消息
我们说了对于mq丢失消息的话我们可以开启mq的持久化,而且持久化和生产者的confirm机制配合起来,只有消息持久化到了磁盘,才会个生产者发送ack,这样就算是在持久化之前rabbitmq挂了,数据丢了,生产者收不到ack回调也会进行消息重发。

3.消费者丢失消息
使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发