基于可靠消息最终一致性的方案git
• 业务处理服务在业务事务提交前,向实时消息服务请求发送消息,实时消息服务只记录消息数据,而不真正发送。业务处 理服务在业务事务提交后,向实时消息服务确认发送。只有在获得确认发送指令后,实时消息服务才真正发送
• 业务处理服务在业务事务回滚后,向实时消息服务取消发送。消息状态确认系统按期找到未确认发送或回滚发送的消息, 向业务处理服务询问消息状态,业务处理服务根据消息ID或消息内容肯定该消息是否有效
• 被动方的处理结果不影响主动方的处理结果, 被动方的消息处理操做是幂等操做
• 一次消息发送须要两次请求,业务处理服务需实现消息状态回查接口并发
设计图: 设计
实现步骤:
1 .主动方(订单服务)在业务事务提交前,向实时消息服务请求发送消息,实时消息服务只记
录消息数据,而不真正发送。只将消息保存到DB,状态status为等待确认(WATING_CONFORM)。[步骤①,步驟a发送到mq的步骤还未执行,目前只是预发送(保存消息到DB)]blog
2 .主动方执行具体的业务(好比操做订单相关的逻辑,步驟②),若是没有问题,调用消息服务,发送消息到mq,而且更新消息表为执行中状态(SENDING)[步骤③]接口
3 . 消息服端监听到消息后,调用被动方(会计服务)业务接口(好比操做会计凭证),若是成功(步骤d),调用消息服务确认系统,删除存储的消息[步骤e]事务
在步骤f有个消息恢复系统,主要处理两种异常状况:
i: 处理步驟②,执行具体业异常或者超时时,此时消息没有发送到MQ,且DB中存储的消息状态仍是WATING_CONFORM,消息恢复子系统将这部分的数据拿出来从新发送,
此时须要注意,判断幂等性,由于存在执行步驟②【好比操做订单表】成功了,只是超时了,这个时间就须要判断订单是否是已经成功了,若是成功了就确认并发送消息,不然
直接删除这条消息(由于确定是订单业务失败了,会回滚)
ii:处理3中,调用被动方业务失败的状况,此时失败,就不会调用消息服务的确认系统,消息还存储在DB中,此时状态为SENDING,经过消息恢复系统,将这部分的数据从新发送MQ【注意有最多发送次数,超过期,直接设置该消息死亡状态】it
异常处理状况:
1.主动方预发送消息(存储DB)[步骤①] ,而后执行具体业务时(处理成功的状况),超时致使异常,此时步骤③没有执行,这时会经过消息恢复子系统从新处理(重发消息到mq,更改DB状态SENDING)
若是业务执行失败的状况,会经过消息恢复子系统直接删除DB里的消息。[由于异常致使回滚,整个业务都是失败的]
2. mq宕机,会通关消息回复子系统重发消息
3. 消息服务端监听后执行被动方业务失败或者超时,此时会通关消息回复子系统重发消息下载
目前本身搭建了一个环境,是开源的项目 reliable-message(提供服务) + reliable-message-samples(消费业务)这两个项目组成了一个 中间消息服务请求
项目开源可在git 下载im