因为公司本身的支付系统比较复杂,我这边删减掉了一大部分功能,主要针对回调通知这块业务来做分布式事物的说明,这块业务也是所有支付业务里面最重要的业务,对数据一致性要求最高的一块业务。下面我们来看简化后的第三方支付系统的系统架构图。
说明:
3rd-access可以理解成一个支付网管,所有支付请求和支付结果回调都通过它进行分发。
途中每一个小各自代表一个独立的系统,整个架构采用微服务的形式。
整个请求的流程在图中已经画的很明显,在此不做特殊的说明。我们要做的是来分析,每一步的流程,或者服务的宕机造成的数据丢失问题。
1:发起支付,如果这步因为3rd-access或者网络原因,不能进行,那么所有用户都不能进行付费,虽然支付系统挂了,但是数据目前来说还是一致的,只是都是失败而已。
2:创建支付订单,如果这步因为订单服务宕机或者网络原因引起用户不能下单,那么同上。
3:选择支付方式,如果这步因为支付插件宕机造成取不到对应的支付方式,但是现在订单库已经有订单了,只是订单的状态目前还是“支付中”,并没有支付成功,在程序上其实默认还是默认失败的,所以只是整个支付失败而已,并不会造成支付数据的丢失。
4:支付回调,这步我们不可控暂时先忽略。下面的分析,都默认支付结果都正常回调
5:更新状态,当比如支付宝已经付款成功(钱已经扣了),支付宝也成功将订单的支付结果回调到我们的支付网关了(3rd-access)。如果在更新订单的时候,因为订单系统宕机了,那么本来应该更新支付订单的状态为"支付成功"的,现在因为服务挂了,订单表该笔订单还是“支付处理中”的状态,那么相当于用户的钱白扣了,所以step5会造成支付数据的丢失,导致数据不一致的问题。
6:通知商户支付结果,假设第5步是更新成功的,数据的订单状态为"支付成功"。但是在通知商户的时候,因为商户的服务挂了或者网络有问题,那么该通知就不能成功通知到商户(用户),导致扣取了用户的钱,但是没有下发对应的权益。所以step6也会造成支付数据的丢失,导致数据不一致的问题。
7:通知"积分","营账","充值"系统,这个跟通知商户类型,只是这个是通过接口异步通知的,另一个是通过http的方式进行通知的。这部分也会造成明明订单是成功的,订单状态已经是“支付成功”,但是对应的积分没加,对应对账系统也没加,导致后期订单库与其他系统数据对不上,造成脏数据的问题。
数据的一致性,服务的高可用是支付系统的核心,因为分分钟都是钱啊。
下面标红的地方就是可能发生数据丢失的地方,我们再来看一边。
这些服务都是分布式独立部署的,有的甚至是多节点部署,很显然利用传统的本地事物是处理不了的。
那么如何设计分布式事物的方案,解决数据不一致的问题呢?不要急下面的文章会为大家解答。
/**
* ————————如果觉得本博文还行,别忘了推荐一下哦,谢谢!
* 作者:写程序的奥特曼
* 欢迎转载,请保留此段声明。
* 出处:https://my.oschina.net/u/2286631/blog/1504582
*/