虽然现在主流都是RocketMQ ,但是技术底层都是差不多,关于RabbitMQ 现在应该还是会有人使用的。这里简单记录一下关于我对RabbitMQ 可靠性这一块的理解。
RabbitMQ 丢失数据的场景,一般就几种:
-
消息在传入过程中丢失
这里就是生产者将数据发送到RabbitMQ 服务器的时候,数据因为网络等等问题 在传输的半路没有到达。
解决思路:
(1) 此时可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect
,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback
,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit
。
不过选择事务机制会很消耗性能,降低吞吐量,如果能接受这个性能的差距 使用也可以的。
(2) 开启confirm
模式。
说明:事务机制和confirm
机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm
机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息 RabbitMQ 接收了之后会异步回调你的一个接口通知你这个消息接收到了。 -
RabbitMQ 收到消息,暂时写入缓存,消费者还没消费,突然挂掉内存数据丢失
RabbitMQ 自己弄丢了数据,这个你必须开启RabbitMQ 的持久化
,就是消息写入之后会持久化到磁盘,哪怕是 RabbitMQ 自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。除非极其罕见的是,RabbitMQ 还没持久化,自己就挂了,可能导致少量数据丢失,但是这个概率较小。
设置持久化的步骤自行查阅。 -
消费者消费到这个消息,但还没来得及处理就挂了,此时mq也会认为消息已处理
一般来说 ,消费者的丢失就是 ,刚消费到,还没处理,结果进程挂了,然后mq认为已处理,这个时候就用到RabbitMQ提供的ack机制,关闭mq的自动ack,然后通过api来进行手动ack ,基本上就不会丢失。
总结
生产者丢失:
方案一: 开启rabbitmq事务机制
方案二: 开启confirm机制
MQ丢失:
方案:开启持久化
消费者:
方案: 关闭mq的自动ack,通过api去手动ack
声明
如有侵权,请联系删除。