MQ消息最终一致性解决方案


     事务消息:实现了消息生成者本地事务与消息发送的原子性,保证消息生成者本地事务处理成功与消息发送成功的最终一致性问题。

     

1、事务消息与普通消息的区别就在于消息生产环节,生产者首先预发送一条消息到MQ(这也被称为发送half消息)
2、MQ接受到消息后,先进行持久化,则存储中会新增一条状态为待发送的消息
3、然后返回ACK给消息生产者,此时MQ不会触发消息推送事件
4、生产者预发送消息成功后,执行本地事务
5、执行本地事务,执行完成后,发送执行结果给MQ
6、MQ会根据结果删除或者更新消息状态为可发送
7、如果消息状态更新为可发送,则MQ会push消息给消费者,后面消息的消费和普通消息是一样的

        注意点:由于MQ通常都会保证消息能够投递成功,因此,如果业务没有及时返回ACK结果,那么就有可能造成MQ的重复消息投递问题。因此,对于消息最终一致性的方案,消息的消费者必须要对消息的消费支持幂等,不能造成同一条消息的重复消费的情况。

  如果consumer消费失败,是否需要producer做回滚?

  答:事务消息,producer不会因为consumer消费失败而做回滚,采用事务消息的应用,其所追求的是高可用最终一致性,消息消费失败的话,MQ自己会负责重推消息,直到消费成功。因此,事务消息是针对生产端而言的,而消费端,消费端的一致性是通过MQ的重试机制来完成的。

基于本地消息的最终一致性
       

 

       基于本地消息的最终一致性方案的最核心做法就是在执行业务操作的时候,记录一条消息数据到DB,并且消息数据的记录与业务数据的记录必须在同一个事务内完成,这是该方案的前提核心保障。在记录完成后消息数据后,后面我们就可以通过一个定时任务到DB中去轮训状态为待发送的消息,然后将消息投递给MQ。这个过程中可能存在消息投递失败的可能,此时就依靠重试机制来保证,直到成功收到MQ的ACK确认之后,再将消息状态更新或者消息清除;而后面消息的消费失败的话,则依赖MQ本身的重试来完成,其最后做到两边系统数据的最终一致性。

        问题:每个业务系统在使用该方案时,都需要在对应的业务库创建一张消息表来存储消息,可以将该功能单独提取出来,做成一个消息服务来统一处理

独立消息服务的最终一致性

  

  过程其实就是模拟了事务消息的消息预发送过程,如果预发送消息失败,生产者业务就不会去执行,对于生产者的业务而言,它是强依赖于该消息服务的。不过好在独立消息服务支持水平扩容,只要部署多台,做成HA的集群模式,就能够保证其可靠性。在消息服务中,还有一个单独地定时任务,会定期轮训长时间处于待发送状态的消息,通过一个check补偿机制来确认该消息对应的业务是否成功,如果对应的业务处理成功,则将消息修改为可发送,然后将其投递给MQ;如果业务处理失败,则将对应的消息更新或者删除即可。因此在使用该方案时,消息生产者必须同时实现一个check服务,来供消息服务做消息的确认。对于消息的消费,该方案与上面的处理是一样,都是通过MQ自身的重发机制来保证消息被消费。

 

      

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM