RabbitMQ消息可靠性、重复、顺序问题、集群

可靠性

RabbitMQ消息可能丢失消息的地方

1、消息从生产到交换机

2、消息从交换机到队列

3、在队列还未被消费时宕机

4、消息消费时失败

对应解决

1、RabbitMQ有ack机制,当send消息到交换机成功时会返回ack消息,失败则nack publish-confirm生产者方channel开启confirm模式,然后增加监听,注意这时候可能由于网络波动可能已经消息入队但生产者主观认为失败,而再次发送(即可能出现重复消息,目的是为达到最少一次消费)。

confirm 单个消息

mandatory到不到队列

事务,多个消息

2、当交换机到队列失败会返回ack报文与publish-return,成功publish-confirm

3、队列可以开启持久化机制(没25ms落盘,还是有可能丢失,万一就在25ms内到达又宕机)

4、关闭autoack,启动手动ack防止方法出现异常或者其他原因而没有成功消费消息的情况下告知MQ自己已经成功消费。

重复

综上所述,虽然已经做了重重机制保证消息不丢失至少消费一次但是还是有可能丢失,也有可能出现重复消息,如果真的丢失消息可通过日志系统由开发人员处理(丢失的概率很小)。

对于重复消息来说,可以实现消息的幂等性消费。在发送时为消息添加UUID,在消费时将消息ID缓存在数据库中,消费之前先判断该消息是否消费过,如果确实没有再消费此消息。

结合CAS还可以有另一种思路,对于某个消息要改变的实体(增删改),删肯定会判断数据库中是否存在该实体,不管几次删除都是一样的结果,增则确保存在唯一ID并添加唯一键,而改可以在消息中添加实体原始数据,消费者更改实体时先比较真实值与期望值再决定是否修改数据(如果真实值与期望值不一致则说明消息可能被消费过(可能另一个生产者的消息也是要更改该实体并且已经更改,还是唯一ID好))。

顺序

消息队列由于消息消费失败可能会重新入队或者多消费者监听同一个队列而存在消息不满足顺序性的可能,可以在业务上一个队列只有一个消费者,消息失败的则进入失败队列而不是重新入队。再有一个业务来处理失败消息队列如此保证消息消费的顺序性。

集群

普通集群,都保存元信息(队列、交换机、绑定)。将队列分散在不同的节点上,消息单份宕机则只能等待重新启动才能消费。 

镜像集群,在普通集群的基础上,消息多份主从同步(数据非强一致)。主节点提供读写,从节点不提供读写,主节点挂掉按节点加入时间升级主节点。主节点宕机从节点成为新主节点,期间unack消息重新入队。可指定消息备份数量,或所有或指定节点。一个消息消费后通知其他队列删除消息,实现高可用。

仲裁队列(3.8版本),也是主从,仲裁队列是raft协议实现,数据一致性更强。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值