System-A为主系统
流程描述
1. system-A执行本地事务,
发送msg到redis,此时msg状态为unknown(这里全是unknown状态的msg,消息需要持久化,只有msg存在,即使system-b处理失败也可以有其他方式处理,一般是人工)
2.1本地事务提交
2.1.1 更改redis的msg状态为提交,从老的内存队列删除,并放入另一个内存队列(这里全是commit状态的msg)
2.1.2 monitorsystem负责把commit状态的msg发送到MQ,并把msg转移到commited的存储中
2.2.本地事务回滚
2.2.1删除redis中的msg
3.System-B执行事务
3.1从MQ接收msg,执行本地事务,需要有重试的机制和避免重复处理的能力。(当超过最大重试次数后还失败,则需要预警,人工参与处理。)
3.2处理成功后需通知system-a,system-a做相应处理,并删除redis中的msg
4.处理完通知
5.补偿通知
Monitorsystem的作用
1. 监控commit状态的msg 进行发送
2. 监控unknown状态的msg,根据具体逻辑去检查system-a,看看system-a的事务是否成功,来变更msg的状态。
3. 监控commited状态的msg,若过了一段时间还存在,则可能system-b通知失败,则monitor system去查system-b,然后进行补偿通知。
用来保证system-a成功的事务的消息可以发送,如果事务失败,则消息是unknown状态也不会被下游系统处理。
Messageresend system
基于某些情况,消息丢失,需要可以从system-a生成msg重新投递。
Precommit 阶段选择redis的理由
本来开始想用MQ来存储,由于这是消息的中转阶段,因为需要根据msgId对消息进行查询,然后还得更新已存在的消息的数据(状态值),然后查看了几个mq中间件,比较activemq,metaq,前者不支持查询消息,而对于更新消息状态则都不支持。所以mq无法支持这种消息中转存储。
参考:
http://blog.jobbole.com/89140/