RabbitMQ使用过程中,可能存在数据丢失的情况,在生产者、RabbitMQ、消费者之间进行数据传输及逻辑处理过程中均有可能会出现数据丢失问题。
1. 生产者弄丢了数据
生产者将数据发送到rabbitmq的时候,可能数据在半路给搞丢了,比如因为网络问题等。
此时可以采用rabbitmq提供的事务功能,就是生产者发送数据之前开启rabbitmq事务(channel.txSelect),然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会收到异常报错,此时就可以回滚事务(channel.txRollback),然后重试发送消息;如果收到了消息,那么可以提交事务(channel.txCommit)。但是问题是,rabbitmq事务一开,会同步阻塞卡住,基本上吞吐量会下来,因为太耗性能了。可以采取confirm机制:
1先将channel设置为confirm模式
2生产者发送一个消息
3发送消息完成后生产者不管了
4rabbitmq如果接收到了发送的消息,就会回调生产者本地的接口,通知生产者收到发送的消息
5rabbitmq如果在接收消息的时候出现异常,就会回调接口,通知生产者消息接受失败,可再次重发消息
生产者要保证不丢失数据,一般使用confirm机制,异步的模式发送消息后不会阻塞下一个消息的发送,不会造成吞吐量的降低。
2. rabbitmq弄丢了数据
RabbitMQ自己弄丢数据的情况,需要开启rabbitmq的持久化,在消息写入后持久化到磁盘,设置持久化有两个步骤:
1创建queue的时候将其设置为持久化,保证rabbitmq持久化queue的元数据,但是不会持久化queue里面的数据。
2发送消息的时候将消息的deliveryMode设置为2,即将消息设置为持久化的,此时rabbitmq就会将消息持久化到磁盘中。
必须要同时设置这两个持久化。且持久化可以跟生产者的confirm机制配合,只有当消息被持久化到磁盘后,才会通知生产者。
3. 消费者弄丢了数据
消费者刚收到消息,结果进程挂了,比如重启了,rabbitmq就会认为消费者已经消费,造成数据丢失。
可以使用rabbitmq的ack机制,关闭rabbitmq的自动ack。
ack机制默认打开,ACK机制是消费者从RabbitMQ收到消息并处理完成后,反馈给RabbitMQ,RabbitMQ收到反馈后才将此消息从队列中删除。
如果一个消费者在处理消息出现了网络不稳定、服务器异常等现象,那么就不会有ACK反馈,RabbitMQ会认为这个消息没有正常消费,会将消息重新放入队列中。
如果在集群的情况下,RabbitMQ会立即将这个消息推送给这个在线的其他消费者。这种机制保证了在消费者服务端故障的时候,不丢失任何消息和任务。
消息永远不会从RabbitMQ中删除,只有当消费者正确发送ACK反馈,RabbitMQ确认收到后,消息才会从RabbitMQ服务器的数据中删除。
每次消费者处理完成之后,通过api手动ack,如果没处理完或者是处理异常,就没有ack,rabbitmq会把这个消费分配给别的consumer(消费者)处理,消息不会丢失。
标签:持久,生产者,rabbitmq,发送,丢失,RabbitMQ,数据,消息 From: https://www.cnblogs.com/wangfeng2013/p/16860730.html