复制代码
TCC适用于公司内部对一致性、实时性要求较高的业务场景,而本文咱们讲解的“最大努力通知型事务”是为解决跨网络、跨服务之间的柔性事务的另外一种解决方案。数据库
首先看一下最大努力通知型的流程图,以下图bash
咱们根据图中的内容,逐步分析一下该方案的业务流程。网络
1. 原理并发
首先阐述一下该方案的原理,根据图中所示,框架
业务活动的主动方(通知发起方),在完成本地业务活动处理后,会向业务活动被动方发送消息【箭头1】, 将业务执行结果通知给业务被动方【箭头4】。这个过程容许消息丢失,若是发生丢失的状况,服务主动方可以经过重试尽力实现双方的数据一致性。此处的的重试就体现出了–最大努力 的特色。异步
而后是业务的被动方。业务被动方会暴露一个业务结果接收接口(或者叫回调接口也能够)给业务主动方【箭头4】,对收到的通知消息进行必要的校验,校验经过后执行本地业务,从而使业务达到闭环。分布式
同时,因为主动方对被动方的通知次数是有限的,即咱们不可能无限制的通知,所以业务活动主动方须要提供一个业务查询补偿接口供被动方使用【箭头5】,被动方会根据定时策略,向业务活动的主动方发起查询操做,从而对丢失的业务消息达到补偿的目的。优化
整个过程当中,业务被动方暴露给主动方的通知接收接口 以及 业务主动方提供给被动方进行查询操做的接口均须要实现幂等,这样才能保证数据完整性不会被破坏,从而实现最终一致性。spa
2. 详解code
接下来,咱们详细展开对该方案的讲解。
在这个方案中,咱们要求被动方的业务处理结果不能影响业务主动方的处理,双方的职责是清晰的,例如:咱们接入支付宝的支付功能,我方的身份即业务被动方,而支付宝方则为业务主动方。
我方接收到用户的支付请求,等待用户输入支付密码,用户支付确认后,我方向支付宝发起支付请求,同步返回给用户预支付结果。此时,用户看到支付处理中。
当支付宝侧执行转帐完成以后(图中的箭头1),结果能够是成功/失败,总之主动方必定是在本地业务有肯定的执行结果后,才会发起通知。
支付宝侧会经过某种机制(猜测是图中的消息队列机制)将通知请求扔到通知消息服务中,通知发送核心业务消费通知消息,并记录持久化消息到数据库中,发送通知消息给我方。
我方支付回调接口收到支付完成通知后,会对参数进行签名校验,待签名经过后,取出业务参数,对这笔支付订单返回的结果进行后续操做(修改状态为下单完成并发货或者修改成支付失败,操做回滚/退款)。
这个过程理想状态下是很快的,因为支付宝侧强大的处理能力,咱们几乎感受不处处理中状态,但整个过程确实是异步的过程。
【这里给咱们的启示之一即是,对于跨系统的交互,若是可以将同步的业务操做拆分为异步过程,可以大幅度提升业务的灵活度及吞吐量。】
这里存在一种广泛的状况,咱们的系统处理能力是有限的,在收到通知后未能及时的处理完成,这时,双方会约定,若是收到通知且处理完成,业务被动方须要返回肯定某个状态码,如:“success”,不然认为这次通知失败。
这样,只要咱们处理完成就返回“success”,主动方就不会继续通知。不然,主动方会按照必定策略,好比“时间衰减策略”,对通知失败的请求从持久层中取出,好比:24小时内,按照间隔1min、5min、10min、30min、1h、2h、5h、10h的方式,逐步拉大通知间隔,直到达到通知要求的时间窗口上限。这时,就须要被动法主动发起查询。通常这种状况不多,而这么作的目的也是为了使最近的请求更快的被通知回去,咱们认为,时间越靠后,通知成功的可能性越少,由于大多数的通知请求在第一次通知发起时就返回了成功success。
PS:这里还有一种措施,就是人工干预,重置通知位点。好比:若是达到最大通知次数依然没有通知成功,那么数据仍旧保存在通知库里面,运营人员在接收到商户的重复通知需求的时候,经过人工的操做,从新重置通知次数,这样消息就能够从新通知了。
这种状况每每是业务被动方未接入主动查询致使的,不建议频繁采用此方案,正常的流程时在开发阶段就强烈要求被动方将通知接口及查询接口均开发完成。
说多了都是泪,笔者曾经在工做中从事过一段时间商户接入工做,就遇到过这种类型的商户,常常要求咱们为他们从新发起通知,对工做效率的影响真是肉眼可见的。
咱们说回正题,在异常状况下,若是业务主动方在必定时间阈值内未能及时的发起通知,而做为业务被动方的咱们又想及时获取到业务结果,这时就须要业务被动方主动发起查询,调用主动方暴露的查询接口获取业务结果,这里通常采用定时做业轮询,从而在业务上达到闭环, 最大可能的保证了数据的一致性。
3. 方案评价
4. 实现方式
从本文开始的图中能够看出,一般采用两种方式实现
5. 如何优化
6. 小结
本文对分布式事务解决方案的– 最大努力通知型 柔性解决方案进行了较为详细的讲解,结合实例及笔者的工做经历,对方案的各个细节展开讲解,但愿可以对读者有所帮助。
后续笔者会着手开发一款分布式事务的轮子,入手点将采用本文提到的模式,并最终达到基本可用。算是立了一个flag吧,完成以后会第一时间发文出来。(又一个有生之年系列)
到目前为止,《我说分布式事务》 系列就过半了,以后我会对可靠消息一致性方案进行讲解,咱们不见不散。