⼀⾏代码,保障分布式事务⼀致性—GTS:微服务架构下分布
式事务解决⽅案
摘要: 虽然微服务现在如⽕如荼,但对其实践其实仍处于初级阶段。即使互联⽹巨头的实践也⼤多是试验层⾯,鲜有核⼼业务系统微服务化的案例。GTS是⽬前业界第⼀款,也是唯⼀的⼀款通⽤的解决微服务分布式事务问题的中间件,⽽且可以保证数据的强⼀致性。本⽂将对GTS做出深⼊解读。
微服务倡导将复杂的单体应⽤拆分为若⼲个功能简单的、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。概念2012年提出迅速⽕遍全球,被越来越多的开发者推崇,很多互联⽹⾏业巨头、开源社区等都开始了微服务的讨论和实践。根据Netflix云架构总监Adrian Cockcrof,Hailo有160个不同服务构成,NetFlix有⼤约600个服务。国内⽅⾯,阿⾥巴巴、、、京东、等很多互联⽹公司都进⾏了微服务化改造。当前微服务的开发框架也有⼏⼗种之多,⽐较著名的有、、 、等。
1 分布式事务解决⽅案及其弊端
虽然微服务现在如⽕如荼,但对其实践其实仍处于初级阶段。即使互联⽹巨头的实践也⼤多是试验层⾯,鲜有核⼼业务系统微服务化的案例。⽽对于很多中⼩型互联⽹公司,鉴于经验、技术实⼒等问题,微服务落地更加困难。世界著名的软件架构⼤师在⼀⽂中也直接了当的指出了微服务当前存在的问题:
对于第⼀和第三个问题,笔者认为随着RPC框架的成熟,已经逐渐得到解决。例如dubbo可以⽀持rmi、hessian、http、webservice、thrift、redis等多种通讯协议,springcloud可以⾮常好的⽀持restful调⽤。spring体系下应⽤的测试也变的越来越简单。对于第四个问题,随着docker、devops技术的发展以及各公有云paas平台⾃动化运维⼯具的推出,微服务的部署与运维会变得越来越容易。
⽽对于Chris Richardson提到的第⼆个问题,现在还没有通⽤⽅案很好的解决微服务产⽣的事务问题。分布式事务已经成为微服务落地最⼤的阻碍,也是最具挑战性的⼀个。 为此,本⽂将深⼊和⼤家探讨微服务架构下,分布式事务的各种解决⽅案,并重点为⼤家解读阿⾥巴巴提出的分布式事务解决⽅案----GTS。该⽅案中提到的GTS是⽬前业界第⼀款,也是唯⼀的⼀款通⽤的解决微服务分布式事务问题的中间件,⽽且可以保证数据的强⼀致性。
2 SOA分布式事务解决⽅案
在微服务之前,信息系统中的服务⼤多基于SOA的理念设计(),服务相对⽐较重。对于服务调⽤产⽣的分布式事务问题,在SOA时代,就有⼀些解决⽅案。⽐较著名的有基于XA协议的⽅案、TCC⽅案、消息最终⼀致性⽅案。
2.1基于XA协议的⽅案
该⽅案最早由oracle提出⽤于解决跨数据访问的事务问题,是⼀种强⼀致性的解决⽅案,由事务协调器和本地资源管理器共同完成。事务协调器和资源管理器间通过XA协议进⾏通信。XA协议实现的原理⼊下图所⽰,共分为两个阶段,也就是我们常说的两阶段协议。
两阶段⽅案在解决数据库分布式事务问题⽅⾯应⽤⾮常⼴泛,oracle、Mysql等主流关系数据库均⽀持XA协议,⽽且ocenbase、DCDB等著名的分布式数据库也都基于两阶段协议。在解决服务事务问题上,其实 XA协议不是只能作⽤于单个服务内部的多资源场景,跨服务的多资源场景也是可以的,只不过需要额外的事务传递机制。但其都有致命的缺点,性能不理想。由于需要等到各分⽀事务都就绪后全局事务才开始提交,所以每个事务锁定数据的时间较长,XA⽅案因此很难满⾜⾼并发场景。⽽且在解决微服务问题时XA⽅案的性能问题将会被放⼤。因为应⽤在访问服务的调⽤⽅式、⽹络环境等要⽐访问数据库复杂的多。例如,应⽤和其访问的数据库通常在⼀个局域⽹中,⽽其通过rpc调⽤的服务则可能属于另⼀个⽹络或者在公⽹上,其时延更长、出故障的概率更⾼。这将导致数据锁定时间和系统并发度进⼀步降低。所以XA⽅案基本不适合解决微服务的事务问题。
2.2TCC⽅案
应⽤是⽬前呼声最⾼,也是落地最多的⼀个⽅案。当前也有⼀些开源的TCC框架实现,如、。TCC⽅案其实是两阶段⽅案的⼀种改进,其将本地资源管理器的功能融⼊到了业务实现中。其将整个业务逻辑显⽰的分成了Try、Confirm、Cancel三部分。try部分完成业务的准备⼯作,confirm部分完成业务的提交,cancel部分完成事务的回滚。基本原理如下图所⽰。
事务开始时,业务应⽤会向事务协调器注册启动事务。之后业务应⽤会调⽤所有服务的try接⼝,相当于XA的第⼀阶段。如果有任何⼀个服务的try接⼝调⽤失败会向事务协调器发送事务回滚请求,否则发送事务提交请求。事务协调器收到事务回滚请求后会依次调⽤事务的confirm接⼝,否则调⽤cancel接⼝回滚,这相当于XA的第⼆阶段。如果第⼆阶段接⼝调⽤失败,会进⾏重试。
TCC⽅案通过通过三个接⼝很好的规避了长时间数据加锁的问题,业务表在每个接⼝调⽤完毕即可释放,这很⼤程度上提⾼了业务的并发度,这也是TCC⽅案最⼤的优势。所以在SOA时期,TCC⽅案被
很多⾦融、电商的业务系统⼤量使⽤。
当然TCC⽅案也有不⾜之处,集中表现在以下两个⽅⾯:
开发⼯作量⼤。它将部分资源管理器的功能融⼊到每个服务的开发中,导致服务的每个接⼝都需要实现try、confirm、cancle,还需要实现事务协调器,开发量不只翻了⼀倍。
实现难度⼤。系统需要记录每个应⽤的服务调⽤链路。我前⾯讲过rpc调⽤情况⽐较复杂,由于⽹络状况、系统故障等调⽤失败被视为常态,必须按照不同的失败原因实现不同策略的回滚。为了满⾜⼀致性的要求,⼆阶段不管调⽤confirm还是cancle都必须调⽤成功,如果⼀次调⽤不成功,事务协调器必须尝试重试。这就要求confirm和cancle接⼝必须实现幂等。
上述原因导致TCC⽅案⼤多是被研发实⼒较强、有迫切需求的⼤公司所采⽤。其将分布式事务变成⼀种所谓的“贵族技术”,中⼩型企业由于⼈员有限、技术实⼒薄弱,很难落地。⽽且笔者认为微服务倡导的是服务的轻量化、易部署,⽽TCC⽅案将很多事务的处理功能融⼊到业务中,对业务侵⼊性太⾼,导致服务逻辑复杂,⽐较适合⽐较重的服务。
2.3 消息事务⼀致性⽅案
消息⼀致性⽅案是通过消息中间件保证上、下游应⽤数据操作的。基本思路是将本地操作和发送消息
放在⼀个事务中,保证本地操作和消息发送要么两者都成功或者都失败。下游应⽤向消息系统订阅该消息,收到消息后执⾏相应操作。
以下单业务为例进⾏说明,下单基本流程是先存储订单信息,然后扣相应商品的库存,两个操作必须在⼀个事务中。如下图,业务应⽤⾸先调⽤订单服务,订单存储成功后,订单服务会通过消息处理服务投递订单消息到MQ。库存服务从MQ收到消息后进⾏扣库存操作,如果执⾏成功会向消息处理服务发送通知。消息处理服务会实时监测订单消息是否超时,如果超时会重新投递到MQ中,以驱动库存服务进⾏扣库存操作。如果扣库存操作执⾏失败后,库存服务后续还会从MQ接收到相同的订单消息,需要多次重复执⾏,直到成功或者进⾏⼈⼯⼲预。库存服务需要实现幂等。
消息⽅案从本质上讲是将分布式事务转换为两个本地事务,然后依靠下游业务的重试机制达到最终⼀致性。相对TCC⽅案来讲,消息⽅案技术难度相对低,落地较容易,如果对⼀致性不敏感的应⽤也是⼀个不错的选择。美国著名电商以及国内的都做过尝试。消息⼀致性⽅案的不⾜之处是其对应⽤侵⼊性较⾼,应⽤需要基于消息接⼝进⾏改造,⽽且需要建设专门的消息系统,成本较⾼。
3 GTS--微服务分布式事务解决⽅案
,由阿⾥巴巴中间件部门研发,可以为微服务架构中的分布式事务提供⼀站式解决⽅案。GTS⽅案的基本思路是:将分布式事务与具体业务分离,在平台层⾯开发通⽤的事务中间件GTS,由事务中间件协调各服务的调⽤⼀致性,负责分布式事务的⽣命周期管理、服务调⽤失败的⾃动回滚。
GTS⽅案有三⽅⾯的优势,⾸先它将微服务从分布式事务中解放出来,微服务的实现不需要再考虑反向接⼝、幂等、回滚策略等复杂问题,只需要业务⾃⼰的接⼝即可,⼤⼤降低了微服务开发的难度与⼯作量。将分布式事务从所谓的“贵族技术”变为⼤家都能使⽤的“平民技术”,有利于微服务的落地与推⼴。 其次,GTS对业务代码⼏乎没有侵⼊,只需要通过注解@TxcTransaction界定事务边界即可,微服务接⼊GTS的成本⾮常低。第三,性能⽅⾯GTS也⾮常优秀,是传统XA⽅案的8~10倍。
3.1 基本原理
GTS中间件主要包括客户端(GTS Client)、资源管理器(GTS RM)和事务协调器(GTS Server)三部分。GTS Client主要完成事务的发起与结束。GTS RM完成分⽀事务的开启、提交、回滚等操作。GTS Server主要负责分布式事务的整体推进,事务⽣命周期的管理。
GTS和微服务集成后的结构图如上图所⽰。GTS Client需要和业务应⽤集成部署,RM与微服务集成部署。当业务应⽤发起服务调⽤时,⾸先会通过GTS Client向TC注册新的全局事务。之后GTS Server会给业务应⽤返回全局唯⼀的事务编号xid。业务应⽤调⽤服务时会将xid传播到服务端。微服务在执⾏数据库操作时会通过GTS RM向GTS Server注册分⽀事务,并完成分⽀事务的提交。如果A、B、C三个服务均调⽤成功,GTS Client会通知GTS Server结束事务。假设C调⽤失败,GTS Client会要求GTS Server发起全局回滚。然后由各⾃的RM完成回滚⼯作。
3.2 GTS的关键机制
可⽤性
GTS服务也是由多个节点构成的⾼可⽤集,可以弹性扩张,可以接收⾼并发的客户端请求。可以⽀持跨机房部署,⽀持同城容灾和两地三中⼼容灾。任何异常情况下的保证⾼可⽤。
⾃动回滚策略
当有微服务调⽤失败时,GTS服务可以驱动各微服务的RM替微服务完成调⽤的回滚⼯作。举个转账的例⼦,转账应⽤通常调⽤存款服务和扣款服务完成转账功能。先调⽤扣款服务从A账户扣掉100元,然后调⽤存款服务向B账户中存款100元。如果转账应⽤在调⽤存款服务失败时,GTS Client会要求GTS
Server发起回滚,然后通知扣款服务对应的RM,RM会直接在A账户增加100元。然后GTS Server通知转账应⽤回滚成功。从这个过程可以看到,在调⽤服务失败后,其实微服务不⽤做任何⼯作,⽽是由RM替微服务执⾏反向操作,也很⾃然的避免了幂等操作。TCC⽅案中,事务协调器需要显⽰调⽤微服务的反向向接⼝,如果反向接⼝调⽤失败还需要不断重试。
可扩展性
有些情况下,应⽤需要调⽤第三⽅系统的接⼝或者不是基于GTS开发的微服,GTS⽆法接⼊到这些服务的实现中。此时需要⽤到GTS的MT模式。GTS的MT模式可以等价于TCC模式。
MT模式预留了⼀阶段和⼆阶段的提交接⼝,允许应⽤介⼊GTS的两阶段提交。应⽤将提交及回滚接⼝注册后,GTS会⾃动完成调⽤。
隔离级别
GTS⽬前⽀持读未提交和读已提交两种隔离级别。
3.3 GTS与其他⽅案的对⽐
1. 和XA⽅案对⽐
相⽐XA⽅案,GTS更加通⽤,可以对上层业务屏蔽底层实现细节,对业务⼏乎没有侵⼊。这⼀点在微服务时代特别有⽤,微服务⾯对的是⼤量的中⼩企业,甚⾄是个⼈开发者,业务诉求不尽相同,普适、标准的分布式事务产品是⾮常有必要的,可以让开发者从底层技术细节中脱离出来,更专注于业务逻辑的实现,从⽽获得更⾼效、快速的业务发展。两个⽅案都可以遵循ACID特性,都可以实现事务的强⼀致性。GTS性能要⽐XA⽅案⾼。
2. 和TCC⽅案对⽐
GTS⽅案和TCC⽅案最⼤的区别是实现分布式事务实现的层⾯不同。TCC⽅案选择从业务层⾯实现分布式事务功能,将事务的回滚、重试等功能在微服务中实现。⽽GTS选择从中间件层⾯解决分布式事务问题,对微服务⼏乎⽆侵⼊。两个⽅案都可以获得⽐较好的性能,都可以保证调⽤的⼀致性。TCC⽅案实现难度⽐较⼤,适合技术实⼒较强的团队。GTS⽅案可以实现事务的强⼀致性,另外采⽤GTS⽅案后微服务会更简单,耦合性也⾮常低。TCC主要提供开发框架,实现需要依赖业务⽅,⽽GTS是完整的分布式事务解决⽅案,所有分布式事务问题不需要业务⽅介⼊。
3. 和消息最终⼀致性对⽐
相⽐消息⽅案,GTS⽅案侵⼊性⾮常低,可以实现数据的强⼀致性。采⽤消息⽅案,上下游服务之间有很强的耦合性,测试、部署都不是很⽅便,需要单独建设消息系统。不过消息⽅案实现相对简单,
如果对⼀致性要求不⾼,也是⼀个选择。
3.4 GTS的应⽤场景
GTS可应⽤在涉及服务调⽤的多个领域,包括但不限于⾦融⽀付、电信、电⼦商务、快递物流、⼴告营销、社交、即时通信、⼿游、视频、物联⽹、车联⽹等,详细介绍可以阅读 ⼀⽂。
3.5 GTS的输出形式
GTS⽬前有三种输出形式:通过公有云平台输出、通过公⽹云服务输出、通过专有云平台输出。
1 通过公有云平台输出
这种输出形式主要⾯向阿⾥云⽤户。如果⽤户的业务系统已经部署到阿⾥云上,可以直接公有云GTS。开通后业务应⽤即可通过GTS保证服务调⽤的⼀致⾏。这种使⽤场景下,业务系统和GTS间的⽹络环境⽐较理想,GTS能提供更低的响应时间。
公有云提供了⽐较丰富的与dubbo、SpringCloud等集成的样例,可以查看。
分布式和微服务的关系
2 通过公⽹云服务输出

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。