事物问题是很多开发者和设计者非常头疼的问题,本文主要介绍阿里巴巴GTS-全新的分布式事务解决方案的思路。GTS提供完整的事务解决方案,可以解决跨数据库事务问题,微服务化的事务问题,消息事务问题和混合事务问题,同时保证业务的一致性。GTS对应用的侵入性非常低,性能非常强,GTS性能是传统的分布式事务的10倍,4c8g集群可达1.5万TPS,目前最高可达10万TPS。
演讲嘉宾简介:厉启鹏(寈峰),阿里巴巴中间件技术专家
本次直播视频精彩回顾,戳这里!以下内容根据演讲嘉宾视频分享以及PPT整理而成。
本次的分享主要围绕以下四个方面:一、产品简介
二、功能架构
三、典型场景
四、实践操作
1.GTS是什么GTS是一款也是唯一一款专注于分布式事务问题的中间件。我们把它定义为一站式的分布式事务解决方案。也就是说有了GTS之后,用户不再需要考虑到回滚接口的开发,幂等,以及分布式事务引发的其它异常等等。只需要接入GTS,GTS可以保证应用的所有事务问题。我们把事务问题归结为四个方面,也是GTS现在可以解决的四大事务问题。
第一类是跨库问题,实际上,跨库问题是最早碰到的事务问题。这里跨库是指两方面,一方面是有很多的分布式数据库,分布式数据库如果没有事务功能的话,GTS可以为它提供分布式事务的服务。还有一种是跨异构的数据库,或者同构的数据库。比如说业务系统要访问多个MySQL的实例,或者说访问一个MySQL,ObenBase这种异构的数据库,那这时GTS也可以保证跨异构数据库,或者同构数据库的一致性。
第二类是微服务化的事务,在后续这个会有非常广的应用。因为微服务到来之后,传统的服务被划分的粒度非常细。之前一次的RPC调用现在可能要变成若干次RPC调用,这时候它不可避免的会牵扯到事务的问题。我们在GTS公测之后,2月份我们陆陆续续接过来很多的公有云用户,很多都是因为企业在数字化转型的过程中,微服务化之后碰到了跨事务的微服务调用。比如用户买东西的时候,需要保证订单服务,也需要保证库存服务,也要保证它们的一致性。现在很多主流的微服务框架,SpringCloud,Double,EDAS它们实际上框架并没有独立的事务解决方案。这是GTS未来会公开使用的重点场景。
还有一类是消息事务。现在有很多消息组件,有的支持事务功能,有的不支持事务功能。GTS也可以支持消息事务。还有一类是混合事务。有的时候业务系统又要进行本地的SQL操作,还要进行远程的RPC调用,而且还要发消息,这时候GTS可以支持整个事务链上有多种类型的事务,保证多种事务的一致性。
2.GTS与其他解决方案对比在GTS出现之前,业界也是有其它的事务解决方案,第一类是XA方案,第二类是补偿方案,也就是TCC的方案,第三类是消息的方案。
XA方案最早是解决跨数据库的事务问题,它的优势是接口标准化,使用门槛比较低,而且能够达到强一致性的效果。但是有个不理想的是使用了阻塞协议,在高并发的场景下性能不是很理想。而且在微服务化之后可能没办法解决微服务的事务问题。第二类补偿性方案(TCC)其实是比较符合也无需求的,因为它大部分都是按照特定的业务去做开发,它的效率其实取决于开发者的水平。TCC的方案中小型企业其实用的比较少,一方面它需要的人力成本非常高,对开发者的各方面能力有很高的要求。这个方案的不足之处在于非常复杂,每个服务都需求提供一个反向的接口。比如一个下单的操作,还需要一个下单方法的反向回滚的方法,所以说运维成本比较高。第三类消息方案是通过消息异步的补偿一致性,这个方案实现相对简单。但是需要建立独立的消息系统,应用需要跟消息系统耦合在一起,而且需要业务实现幂等,它要求最终一致性,场景会受一些限制,对一致性要求非常搞的场景不太适应。
XA的方案是在资源的层面解决事务问题,因为XA有一个资源管理器是跟数据库放在一起,所以它对于资源是有限制的,现在绝大部分只能支持关系型的数据库,还不是所有的关系型数据库,场景是受限制的。那补偿方案和消息方案是从应用的层面解决事务问题,它们会和应用耦合在一起。GTS跟这三者不同点在于,它既不在资源层也不在应用层,它是在中间件层解决事务的问题,这是它们本质的区别。在中间件有什么好处呢,大概有三点。第一,因为在中间件层,是独立的一层,它可以解决跨资源的问题。如果应用去访问不同类型的问题,比如访问OpenBase,还有MySQL,以及Oracle,这时还需要保证一致性。XA方案很难做到这一点,GTS可以保证异构资源事务的一致性,异构的数据库,甚至文件系统。另外一个好处是GTS不在应用层面,就可以解决服务化问题。另外它和应用是松耦合的,这样应用会更加清亮,比如说一个微服务要解决事务的问题,要实现幂等等操作,它会把非常复杂的解决事务的逻辑嵌入到微服务里,这时微服务已不是微服务,变得非常重。GTS解决事务问题时会让微服务更加简单更加清亮化。而且GTS独立开来,从中间件这层解决事务,便于应用移植。
3.GTS优势下图是从技术层面列的GTS的特点和优势。GTS会提供事务的完整解决方案,第二个是GTS对应用的侵入性非常低,这一点意味着它使用的门槛就很低。如果需要用EDAS的话,只需要加一行注解就OK了,就可以接入到事务中。而且我们还提供了API接入模式,使用非常方便,基本上使用Java开发半年的使用者就可以很方便的使用我们的GTS,我们官方已经有非常完善的文档和样例。还有GTS的性能非常强,通过很多次测试,包括做了要求非常严格的金融行业的测试。是传统的分布式事务的10倍,4c8g集群可达1.5万TPS。我们今年春节的时候淘宝活动,当时有个应用达到了10万TPS,是使用了三个9个节点的集群支持这个应用。除此之外,GTS有高可用的特点。它支持应用宕机,节点故障等各类异常情况下保证数据严格一致,并支持同城主备及两地三中心部署。
4.GTS产品历史大家熟悉的很多平台后面都有GTS的支撑,如淘宝,阿里音乐,盒马生鲜,农村淘宝等等。另外有一些是专有云用户,很多政府部门要建设自己的专有的云平台,GTS也可以以专有云的形式输出。国家的电动汽车交易是基于GTS来保证事务的功能的。另外一部分是公有云用户,大部分是发布阿里云公测之后过来的,包括物流,金融,共享单车,新零售等等一百多个用户。
GTS从2018年5月21日开始商用,首发第一个月内七折,按不同规格分,最高规格年付是六折。
1.总体架构下图是GTS总体的功能架构,左边是总体服务端的集群,GTS一个标准的集群有三个节点,三个节点之间是互备的。右边是GTS客户端,是以SDK的形式与应用集成在一起。客户端负责全局事务的发起,全局事务的结束,全局事务的回滚,分支事务的提交,分支事务的回滚等操作。服务端是全局事务整个生命周期的管理,会记录每个事务的运行状态,每个事务有哪些分支事务,每个分支事务的运行状态。GTS可以跟服务的框架集成,解决服务化事务问题,也可以跟资源对接,解决应用跨资源事务问题。
2.事务模型GTS事务模型非常简单,全局事务包含若干个分支事务。举例来说,一个SQL里面有若干条SQL语句,每个SQL语句就是分支事务。全局事务标识为xid,分支事务标识为branchid,因为服务端会记录每个分支事务的状态,通过模型来组织事务的存储。
3.事务协议下图是客户端和服务端交互的协议。这里的客户端包含两部分,一个是GTS Client,还有一个是RM,也就是资源管理器,通常跟服务集成在一起。首先客户端会往Server端要一个事务的标识xid,拿到之后把xid传给RM,每个RM可能是一个或几个事务分支。RM拿到xid之后会往Server端要分支事务的id,拿到id号代表它以及启动一个分支事务了,这时它可能会提交本地的SQL语句,之后把提交的状态汇报给Server。如果所有的RM执行完毕之后会返回给Client端,Client端告诉Server要全局提交事务,这时整个全局事务就已经提交了。
4.与微服务集成架构下图表示的是有一个业务应用需要调用三个微服务,业务应用通过Server端拿到xid之后,它会把xid传到各个微服务做调用,,每个都做一些数据库操作和资源的访问。如果在调用微服务C的时候失败了,GTS需要回滚前两次操作,回滚是GTS要做的,跟TCC不同。如果有个微服务失败,传到业务应用,业务应用告诉Server,Server会把跟GTS集成咋一起的SDK,SDK里面有RM,RM会让微服务A和B分别做回滚。因为GTS在每次SQL操作之后会记录SQL前后镜像的信息,也就是说之前的数值是知道的,避免幂等的问题,没有必要做反向接口,而是直接回滚就可以了。这一点非常重要,很多从事TCC开发的人员在这方面是非常头疼的。
5.容错机制GTS在服务端,客户端发生异常的时候都可以保证业务的连续性。比如下图,GTS的服务端是个三节点的集群,有三个应用。GTS有一些核心的数据信息,包括锁信息。用户如果牵扯到并发的修改镜像记录是需要有锁的,GTS会把锁信息和各个事务的一些执行状态记录下来,这就是它的关键信息。这些信息是互备的,S1的备到S2上,S2的备到S3上,S3的备到S1上。如果APP正在发生回滚操作的时候,S3挂掉了,APP的RM是知道S3的备用节点的,由备用节点去驱动,完成回滚的操作。
还有一种情况是应用宕机。GTS也可以保证业务的一致性,当然前提是应用是负载均衡部署。
如果说在全局回滚的时候,APP1挂掉了,GTS是知道跟APP1负载均衡在一起的其它APP。GTS可以驱动其它的APP来完成APP1没有完成的回滚的操作。可以完成的核心在于数据在下面的数据库里,只不过找一个跟APP1操作相同,有权限操作相同数据的其它应用干这件事情。
6.扩展机制GTS可以支持应用的横向扩展,如果说三个节点APP非常多,可以通过物理组将这些集群映射到不同的GTS集群。
GTS有两个使用模式,AT和MT。AT是自动模式,可以完全自动回滚,可以覆盖90%左右的业务场景,所以比较推荐使用AT模式,它对业务无侵入,高效,强一致性。还有一种MT模式是GTS推出的兼容TCC的模式,因为有一些情况下是无法避免的要使用TCC模式。而且GTS可以实现两种模式的组合。
场景一:跨数据库场景第一种GTS应用场景,支持跨数据库的事务问题。应用有跨库的操作,跨库的一致性都可以得到保证。
场景二:微服务调用事务问题微服务调用如果有嵌套的场景,GTS可以保证这个调用链条中的事务,也可以保证调用的一致性。
场景三:多系统集成事务问题我们有一个放款应用,它需要调用本地金融系统的三个服务以及第三方系统的服务。用信用核心调用户的信用,而且用风控中心的服务评估放款的风险,之后还需要调用额度中心生成用户放款的额度,最后去银行调银行系统放款。整个调用链需要保证,如果放款失败的话需要回滚前三个服务,因为前三个服务都是由SQL写入。这个场景复杂的点在于不可能回滚第三方系统银行的账户,所以这时候需要用到AT+MT混合的模式。在调用前三个服务的时候使用AT模式,那在调用支用和合法校验的时候必须要使用MT模式,也就是银行那边给你提供一个反向接口,或者自己做一个补偿的反向机制。
场景四:混合事务问题混合事务问题应用也很广,我们有DRDS,MQ,EDAS的调用,只要在一个调用链中,GTS都可以解决。
应用案例我们有一个公有云用户,是共享电动自行车的公司。它有很多的服务,是基于SpringCloud构建的微服务,里面有很多订单,优惠,支付,车辆,运维等很多应用模块。有两个典型的服务就是借车和还车。借车有车况检测,生成订单,变更状态,推送订单消息到MQ,这时候这个调用链中有服务,也有消息的场景。这个过程是通过GTS来保证事务的一致性。还车的时候需要锁车,结束订单,推送消息到MQ,获取优惠券信息,扣款,也是典型的事务。用户从3月份开始上公有云,线上的系统也跑了一段时间,非常稳定,每天的事务量大概在几百万,非常饱和。
下面简单介绍GTS的用法。阿里云的官方网站上有GTS的一些文档和样例工程,这里截取样例工程的案例来展示。下图的案例是个非常简单的转账操作,其中有两个分支,一个是从db1的账户里扣款,然后去另一个账户存款。在后面做一个检测,看刚刚扣款的账户是不是小于零,如果小于零就是没钱了,抛出异常。上面的红色的一行是GTS注解,可以划分事务的边界,如果抛出异常,整个就可以回滚。
使用EDAS客户端也跟上面类似,上面是直接操作数据库。这里也是先加钱再减钱,使用Transaction注解开启一个事务。
下图是EDAS服务端扣款的操作,实际上没有GTS的痕迹,纯业务操作,GTS对服务端代码是没有侵入的。
下图是EDAS的配置文件,需要注意的是这个需要按照GTS的要求进行修改。首先数据源是GTS自己带的txc.datasource,需要这个数据源主要是需要截取镜像信息做回滚。还有一个是TxcTransactionScaner需要配置一下,有三个参数。第一个是逻辑事务分组,主要来标识一个GTS用户的,后面accessKey和SecretKey是阿里云帐号的信息。
下图是MT模式下的操作,在金融行业里面TCC模式用的比较多。MT模式首先需要加注解界定事务的边界,然后通过MtBranch注解告诉GTS第一阶段的资源锁定方法是哪个,然后提交的方法,第二阶段rollback方法是哪个。实现这个接口之后GTS可以按照不同的方法调用。
本文由云栖志愿小组董黎明整理