前边咱们已经学习了四种分布式事务解决方案,2PC、TCC、可靠消息最终一致性、最大努力通知,每种解决方案咱们经过案例开发进行学习,本章节咱们结合互联网金融项目中的业务场景,来进行分布式事务解决方案可行性分析。数据库
P2P金融又叫P2P信贷。其中P2P是 peer-to-peer 或 person-to-person 的简写,意思是:我的对我的。P2P金融指我的与我的间的小额借贷交易,通常须要借助电子商务专业网络平台帮助借贷双方确立借贷关系并完成相关交易手续。借款者可自行发布借款信息,包括金额、利息、还款方式和时间,实现自助式借款;投资者根据借款人发布的信息,自行决定出借金额,实现自助式借贷。网络
目前,国家对P2P行业的监控与规范性控制愈来愈严格,出台了不少政策来对其专项整治。并主张采用“银行存管模式”来规避P2P平台挪用借投人资金的风险,经过银行开发的“银行存管系统”管理投资者的资金,每位P2P平台用户在银行的存管系统内都会有一个独立帐号,平台来管理交易,作到资金和交易分开,让P2P平台不能接触到资金,就能够必定程度避免资金被挪用的风险。并发
什么是银行存管模式?异步
银行存管模式涉及到2套帐户体系,P2P平台和银行各一套帐户体系。投资人在P2P平台注册后,会同时跳转到银行再开一个电子帐户,2个帐户间有一一对应的关系。当投资人投资时,资金进入的是平台在银行为投资人开设的二级帐户中,每一笔交易,是由银行在投资人与借款人间的交易划转,P2P平台仅能看到信息的流动。分布式
银行存管模式:此种模式下,涉及到2套帐户体系,P2P平台和银行各一套帐户体系。投资人在P2P平台注册后,会同时跳转到银行再开一个电子帐户,2个帐户间有一一对应的关系。当投资人投资时,资金进入的是平台在银行为投资人开设的二级帐户中,每一笔交易,是由银行在投资人与借款人间的交易划转,P2P平台仅能看到信息的流动。
标的: P2P业内,习惯把借款人发布的投资项目称为“标的”。
发标: 借款人在P2P平台中建立并发布“标的”过程。
投标: 投资人在承认相关借款人以后进行的一种借贷行为,对本身中意的借款标的进行投资操做,一个借款标可由单个投资人或多个投资人承接。
满标: 单笔借款标筹集齐全部借款资金即为满标,计息时间是以标满当日开始计息,投资人较多的平台多数会当天满标。性能
统一帐号服务学习
用户的登陆帐号、密码、角色、权限、资源等系统级信息的管理,不包含用户业务信息。spa
用户中心设计
提供用户业务信息的管理,如会员信息、实名认证信息、绑定银行卡信息等,“用户中心”的每一个用户与“统一帐号服务”中的帐号关联。3d
交易中心
提供发标、投标等业务。
还款服务
提供还款计划的生成、执行、记录与归档。
银行存管系统(模拟)
模拟银行存管系统,进行资金的存管,划转。
采用用户、帐号分离设计(这样设计的好处是,当用户的业务信息发生变化时,不会影响的认证、受权等系统机制),所以须要保证用户信息与帐号信息的一致性。
用户向用户中心发起注册请求,用户中心保存用户业务信息,而后通知统一帐号服务新建该用户所对应登陆帐号。
针对注册业务,若是用户与帐号信息不一致,则会致使严重问题,所以该业务对一致性要求较为严格,即当用户服务和帐号服务任意一方出现问题都须要回滚事务。
根据上述需求进行解决方案分析:
一、采用可靠消息一致性方案
可靠消息一致性要求只要消息发出,事务参与者接到消息就要将事务执行成功,不存在回滚的要求,因此不适用。
二、采用最大努力通知方案
最大努力通知表示发起通知方执行完本地事务后将结果通知给事务参与者,即便事务参与者执行业务处理失败发起通知方也不会回滚事务,因此不适用。
三、采用Seata实现2PC
在用户中心发起全局事务,统一帐户服务为事务参与者,用户中心和统一帐户服务只要有一方出现问题则全局事务回滚,符合要求。
实现方法以下:
一、用户中心添加用户信息,开启全局事务
二、统一帐号服务添加帐号信息,做为事务参与者
三、其中一方执行失败Seata对SQL进行逆操做删除用户信息和帐号信息,实现回滚。
四、采用Hmily实现TCC
TCC也能够实现用户中心和统一帐户服务只要有一方出现问题则全局事务回滚,符合要求。
实现方法以下:
一、用户中心
try:添加用户,状态为不可用 confirm:更新用户状态为可用 cancel:删除用户
二、统一帐号服务
try:添加帐号,状态为不可用 confirm:更新帐号状态为可用 cancel:删除帐号
根据政策要求,P2P业务必须让银行存管资金,用户的资金在银行存管系统的帐户中,而不在P2P平台中,所以用户要在银行存管系统开户。
用户向用户中心提交开户资料,用户中心生成开户请求号并重定向至银行存管系统开户页面。用户设置存管密码并确认开户后,银行存管当即返回“请求已受理”。在某一时刻,银行存管系统处理完该开户请求后,将调用回调地址通知处理结果,若通知失败,则按必定策略重试通知。同时,银行存管系统应提供开户结果查询的接口,供用户中心校对结果。
P2P平台的用户中心与银行存管系统之间属于跨系统交互,银行存管系统属于外部系统,用户中心没法干预银行存管系统,因此用户中心只能在收到银行存管系统的业务处理结果通知后积极处理,开户后的使用状况彻底由用户中心来控制。
根据上述需求进行解决方案分析:
一、采用Seata实现2PC
须要侵入银行存管系统的数据库,因为它的外部系统,因此不适用。
二、采用Hmily实现TCC
TCC侵入性更强,因此不适用。
三、基于MQ的可靠消息一致性
若是让银行存管系统监听 MQ则不合适 ,由于它的外部系统。
若是银行存管系统将消息发给MQ用户中心监听MQ是能够的,可是因为相对银行存管系统来讲用户中心属于外部系统,银行存管系统是不会让外部系统直接监听本身的MQ的,基于MQ的通讯协议也不方便外部系统间的交互,因此本方案不合适。
四、最大努力通知方案
银行存管系统内部使用MQ,银行存管系统处理完业务后将处理结果发给MQ,由银行存管的通知程序专门发送通知,而且采用互联网协议通知给第三方系统(用户中心)。
下图中发起通知即银行存管系统:
在借款人标的募集够全部的资金后,P2P运营管理员审批该标的,触发放款,并开启还款流程。
管理员对某标的满标审批经过,交易中心修改标的状态为“还款中”,同时要通知还款服务生成还款计划。
生成还款计划是一个执行时长较长的业务,不建议阻塞主业务流程,此业务对一致性要求较低。
根据上述需求进行解决方案分析:
一、采用Seata实现2PC
Seata在事务执行过程会进行数据库资源锁定,因为事务执行时长较长会将资源锁定较长时间,因此不适用。
二、采用Hmily实现TCC
本需求对业务一致性要求较低,由于生成还款计划的时长较长,因此不要求交易中心修改标的状态为“还款中”就当即生成还款计划 ,因此本方案不适用。
三、基于MQ的可靠消息一致性
满标审批经过后由交易中心修改标的状态为“还款中”而且向还款服务发送消息,还款服务接收到消息开始生成还款计划,基本于MQ的可靠消息一致性方案适用此场景 。
四、最大努力通知方案
满标审批经过后由交易中心向还款服务发送通知要求生成还款计划,还款服务而且对外提供还款计划生成结果校对接口供其它服务查询,最大努力 通知方案也适用本场景 。
重点知识回顾:
1)事务的基本概念以及本地事务特性。
CAP、BASE理论的概念。
2PC、TCC、可靠消息最终一致性、最大努力通知各种型原理及特性。
不一样分布式事务类型的应用场景讨论。
RocketMQ事务消息机制。
Seata与传统XA原理上的差别。
2)分布式事务对比分析:
在学习各类分布式事务的解决方案后,咱们了解到各类方案的优缺点:
2PC 最大的诟病是一个阻塞协议。RM在执行分支事务后须要等待TM的决定,此时服务会阻塞并锁定资源。因为其阻塞机制和最差时间复杂度高, 所以,这种设计不能适应随着事务涉及的服务数量增长而扩展的须要,很难用于并发较高以及子事务生命周期较长 (long-running transactions) 的分布式服务中。
若是拿TCC事务的处理流程与2PC两阶段提交作比较,2PC一般都是在跨库的DB层面,而TCC则在应用层面的处理,须要经过业务逻辑来实现。这种分布式事务的实现方式的优点在于,可让应用本身定义数据操做的粒度,使得下降锁冲突、提升吞吐量成为可能。而不足之处则在于对应用的侵入性很是强,业务逻辑的每一个分支都须要实现try、confirm、cancel三个操做。此外,其实现难度也比较大,须要按照网络状态、系统故障等不一样的失败缘由实现不一样的回滚策略。典型的使用场景:满,登陆送优惠券等。
可靠消息最终一致性事务适合执行周期长且实时性要求不高的场景。引入消息机制后,同步的事务操做变为基于消息执行的异步操做, 避免了分布式事务中的同步阻塞操做的影响,并实现了两个服务的解耦。典型的使用场景:注册送积分,登陆送优惠券等。
最大努力通知是分布式事务中要求最低的一种,适用于一些最终一致性时间敏感度低的业务;容许发起通知方处理业务失败,在接收通知方收到通知后积极进行失败处理,不管发起通知方如何处理结果都会不影响到接收通知方的后续处理;发起通知方需提供查询执行状况接口,用于接收通知方校对结果。典型的使用场景:银行通知、支付结果通知等。
3)总结:
在条件容许的状况下,咱们尽量选择本地事务单数据源,由于它减小了网络交互带来的性能损耗,且避免了数据弱一致性带来的种种问题。若某系统频繁且不合理的使用分布式事务,应首先从总体设计角度观察服务的拆分是否合理,是否高内聚低耦合?是否粒度过小?分布式事务一直是业界难题,由于网络的不肯定性,并且咱们习惯于拿分布式事务与单机事务ACID作对比。
不管是数据库层的XA、仍是应用层TCC、可靠消息、最大努力通知等方案,都没有完美解决分布式事务问题,它们不过是各自在性能、一致性、可用性等方面作取舍,寻求某些场景偏好下的权衡。