【重难点】【RabbitMQ 02】如何避免消息重复投递和消息重复消费、如何防止消息丢失、如何保证消息的顺序性、如何保证消息队列的可用性
文章目录
一、如何避免消息重复投递和消息重复消费
为了防止 RabbitMQ 没收到生产者发送的消息,所以生产者需要重复投递。但是消息重复投递就有可能会带来消息重复消费的问题。解决消息重复消费的关键在于消息处理逻辑的幂等性,也就是说同一条消息无论被消费多少次,产生的结果和消息被消费一次是一样的。比如银行要给一个账户增加 50元,我们就可以先查询出账户的余额,假设账户余额为 100 元,然后我们以余额 100 元作为 where 条件对余额进行更新,这样当账户余额增加到 150 元后就无法再查询出这条记录,也就无法再次增加余额了。实现消息处理幂等性的方式没有一个确定的公式,具体实现细节需要根据具体的业务场景来设计
二、如何防止消息丢失
消息丢失可能会发生在生产者、也可能发生在消息队列和消费者。对于生产者来说,每次发送消息后需要收到消息队列返回的确认消息才能保证消息发送成功,如果没有收到确认消息则需要重新发送。对于消息队列来说,需要提高消息队列的可用性,可以通过镜像集群模式来解决。但是没有任何一个系统可以保证不会出现意外情况,所以我们要将重要的消息设置为持久化,这样即使消息队列宕机,消息也不会丢失。对于消费者来说,消费者需要在执行完消息后才能给消息队列返回确认消息,这样即使消息执行失败,也不会返回确认消息,消息队列也就不会删除这条消息,然后可以根据需求选择是否重新发送
三、如何保证消息的顺序性
一个消费者对应一个队列,并且确保需要保证顺序的消息路由在同一个队列中
四、如何保证消息队列的可用性
可以使用镜像集群模式,RabbitMQ 有两种集群模式:普通集群模式和镜像集群模式
普通集群模式并不能保证消息队列的可用性。它的实现方式就是在多台机器上启动多个 RabbitMQ 实例,但是创建的队列只会保存在其中一个实例中,其他的实例只是同步队列的配置信息,通过配置信息来找到队列所在的实例。因此,普通集群模式只能提高消息队列的吞吐量,如果保存队列的实例宕机,那么整个集群还是会失效
镜像集群模式才是 RabbitMQ 的高可用模式,跟普通集群模式的区别在于创建的队列会同步保存在所有实例中,这样即使其中一个实例宕机,还有其他的实例可以正常工作,这样就保证了消息队列的可用性