随着业务的快速发展和业务的日益复杂,传统的单体应用逐渐暴露出一些问题,如开发效率低、可维护性差、架构扩展性能差、部署不灵活、健壮性差等。微服务架构是一个分布式系统,根据业务划分为独立的服务单元,解决了单一系统的缺点,也满足了日益复杂的业务需求。每个微服务只专注于完成一项任务并将其做好。微服务架构的特点微服务架构的优势非常明显,近年来发展迅速。将复杂的业务拆分成多个小业务,可以实现更好的业务复用,有利于服务的人员组织、分工、独立部署和独立扩展,并且每个服务的修改和部署不影响其他服务。每个服务都可以根据业务场景选择合适的编程语言和数据库微服务具有以上优点,但是微服务也带来了很多新的问题,比如:服务数量多,测试、部署、监控难度加大.单体应用拆分成分布式系统后,进程间通信机制和故障处理措施变得更加复杂。系统微服务化后,原本是一个服务的本地数据库事务被拆分成多个服务,需要分布在一个分布式系统中。保证多模式环境下的事务一致性。上述问题中,1和2可以通过近几年出现的各种微服务技术来解决。例如,Kubernetes提供服务发现和服务治理。因此,分布式事务成为微服务实现的最大障碍,也是最具挑战性的技术问题。下面将深入探讨微服务架构下分布式事务的解决方案。从本地事务到分布式事务的演变我们以转账为例。A需要转100元给B,那么需要给A的余额-100元,给B的余额+100元。在单机模式下,可以使用本地事务解决。本地事务将多条语句作为一个整体进行操作的功能称为database_transaction_。数据库事务可以保证事务范围内的所有操作可以全部成功或全部失败。如果事务失败,那么效果就和没有执行这些SQL一样,不会对数据库数据做任何改变。数据库事务具有ACID的四个特性:A:Atomic,原子性,所有的SQL都作为一个原子工作单元执行,要么全部执行,要么根本不执行;C:Consistent,一致性,交易完成后,所有数据的状态是一致的,即只要账户A减去100,账户B就必须加100;I:Isolation,隔离,如果多个事务并发执行,每个事务所做的修改必须与其他事务隔离;D:Duration,持久化,即事务完成后,对数据库数据的修改持久化存储。分布式交易典型场景银行跨行转账业务是一个典型的分布式交易场景,假设A需要跨行给B转账,那么涉及到两家银行的数据,无法通过a来保证转账的正确性一个数据库的本地事务,只能通过分布式事务来解决。在将服务拆分成微服务时,有很多场景需要分布式事务。虽然微服务的最佳实践建议尽量避免分布式事务,但在很多业务场景中,分布式事务是一个无法回避的技术问题。.分布式事务方案常见的分布式事务模式有XA、TCC、SAGA、可靠消息等。下面简单介绍一下两阶段提交/XAXA是X/Open组织提出的分布式事务规范。XA规范主要定义了(全局)事务管理器(TM)和(本地)资源管理器(RM)之间的接口。MySQL等本地数据库在XA中起到了RM的作用。XA分为两个阶段:第一阶段(prepare):即所有参与者RM准备执行事务并锁定所需资源。当参与者准备就绪时,它会向TM报告它已准备就绪。第二阶段(commit/rollback):当事务管理器(TM)确认所有参与者(RM)准备就绪后,向所有参与者发送commit命令。目前主流数据库基本都支持XA事务,包括MySQL、Oracle、SQLServer、PostgreSQL等。一个成功完成的XA事务的时序图如下:TCC事务方案TCC方案实际上是XA提交的改进。它将整个业务逻辑的每个分支明确划分为三个操作:Try、Confirm和Cancel。Try部分完成业务准备,Confirm部分完成业务提交,Cancel部分完成事务回滚。当事务开始时,业务应用程序向事务协调器注册以启动事务。之后,业务应用会调用所有服务的try接口,完成第一阶段的准备工作。之后事务协调器会根据try接口的返回状态决定调用confirm接口还是cancel接口。如果接口调用失败,会重试。一个成功完成的TCC事务的时序图如下:SAGA事务方案Saga和TCC一样,也是一个最终一致性事务,也是一个灵活事务。Saga的本质是将一个长事务拆分成一个个小事务,每个事务包含一个执行模块和补偿模块。Saga没有try,直接提交事务,可能会造成脏读,在一些需要高一致性的场景下是不能接受的。当启动一个Saga事务时,事务管理器会通知第一个Saga参与者,即子事务,执行本地事务。事务完成后,Saga会按照执行顺序调用Saga下一个参与的子事务。这个过程会一直持续到Saga事务被执行。如果子事务对应的本地事务在子事务执行过程中失败了,Saga会以相反的顺序执行补偿事务。一个成功完成的SAGA事务的时序图如下:可靠消息消息一致性方案是通过消息中间件保证上下游应用数据操作的一致性。基本思路是将本地操作和发送消息放在一个本地事务中,保证本地操作和消息发送都成功或都失败。下游应用向消息系统订阅消息,收到消息后进行相应的操作。RocketMQ提供了一个典型的可靠消息接口,可以参考。分布式事务开源项目在分布式事务领域,有java语言的开源项目,以seata为代表。在非Java领域,Go语言的DTM是一个代表项目。DTM支持XA、TCC、SAGA和可靠消息。架构图如下:图中各个角色与XA模型中的角色模型一致,解释如下:AP应用(定义和提交交易,目前支持Go语言,即将支持Nodejs、Python,PHP,Rust等)RM资源管理器(负责管理本地事务,不分语言,只要提供http相关接口)TM事务管理器(DTM,协调全局事务,提交和回滚)在如上架构图,AP通过DTM提供的分布式事务接口与RM、TM进行交互,对现有微服务的侵入很小。另外,在实际业务中,AP和RM的角色可能会重叠。比如在TCC模式下,AP可能有自己的本地事务,同时也注册调用其他事务分支。
