架构总览
Apache Seata 是一款面向微服务架构的分布式事务解决方案,旨在解决分布式环境下的数据一致性问题。该框架通过定义清晰的角色分工和标准化的事务生命周期,为复杂业务场景提供了可靠的事务保障机制。
核心概念与定义
在 Apache Seata 的设计模型中,分布式事务被明确定义为一个层级结构。分布式事务本质上是一个全局事务,而全局事务由一批分支事务组成,每个分支事务通常对应一个本地事务。这种分层设计使得 Seata 能够将复杂的跨服务事务管理问题分解为可管理的本地事务单元。
README.md:47-55 明确阐述了这一核心概念体系,展示了从分布式事务到本地事务的层级映射关系。
| 概念 | 定义 | 职责范围 |
|---|---|---|
| 分布式事务 | 跨越多个微服务的整体事务单元 | 保证全局数据一致性 |
| 全局事务 | 分布式事务的顶层抽象 | 协调所有分支事务的最终状态 |
| 分支事务 | 全局事务的组成部分 | 执行具体的本地业务逻辑 |
| 本地事务 | 单一数据源上的事务操作 | 保证单个资源的数据一致性 |
这种设计理念的核心优势在于:通过将全局事务的复杂性封装在框架层面,业务代码只需关注本地事务的执行,而跨服务的一致性协调则由 Seata 框架自动完成。README.md:51-55 进一步说明了分支事务与本地事务的对应关系。
架构角色划分
Apache Seata 框架定义了三个核心角色来协同完成分布式事务的管理,每个角色承担明确的职责边界。
事务协调者
事务协调者是整个分布式事务架构的中枢神经,负责维护全局事务和分支事务的状态。TC 作为独立的服务端组件运行,不参与具体的业务逻辑执行,而是专注于事务状态的持久化和协调指令的下发。
核心职责:
- 维护全局事务的生命周期状态
- 记录所有分支事务的注册信息
- 驱动全局提交或回滚的最终执行
README.md:59-65 详细定义了 TC 的职责范围。
事务管理器
事务管理器是分布式事务的发起方,通常嵌入在业务应用中。TM 负责定义全局事务的边界,即确定事务的开始、提交或回滚时机。
核心职责:
- 向 TC 申请开启新的全局事务
- 根据业务执行结果决定提交或回滚
- 管理全局事务的上下文传播
README.md:59-65 明确了 TM 在事务边界定义中的作用。
资源管理器
资源管理器管理着分支事务实际操作的资源(如数据库连接),并与 TC 保持通信。RM 负责向 TC 注册分支事务、汇报执行状态,并执行最终的提交或回滚指令。
核心职责:
- 管理分支事务所需的资源
- 向 TC 注册分支事务并汇报状态
- 执行 TC 下发的提交或回滚指令
README.md:59-65 完整描述了 RM 与 TC 的交互机制。
正在加载图表渲染器...
上图展示了三大核心角色的组件构成与交互关系。TC 作为独立服务端运行,TM 和 RM 则作为客户端 SDK 集成在各微服务应用中。
系统架构总览
Apache Seata 采用经典的客户端-服务端架构模式,通过将事务协调逻辑从业务代码中剥离,实现了事务管理与业务逻辑的解耦。
正在加载图表渲染器...
架构要点说明:
-
客户端层:各微服务应用集成 Seata SDK,根据业务角色加载 TM 或 RM 模块。TM 负责全局事务的边界控制,RM 负责本地资源的代理与分支事务管理。
-
服务端层:Seata Server(TC)作为独立进程部署,接收来自所有客户端的事务请求,维护全局事务状态机,并协调各分支事务的最终提交或回滚。
-
存储层:TC 支持多种存储模式,包括文件存储(开发模式)、数据库存储(生产模式)和 Redis 存储(高性能场景),用于持久化事务会话和锁信息。
-
通信协议:客户端与服务端之间通过 gRPC 或 Netty 进行高效通信,确保事务指令的可靠传输。
README.md:57-65 提供了三大角色的定义依据,支撑上述架构设计的合理性。
事务生命周期流程
Apache Seata 管理的分布式事务遵循严格的生命周期流程,确保事务从启动到结束的每个阶段都有明确的状态转换和协作机制。
正在加载图表渲染器...
生命周期关键步骤详解:
步骤 1 - 全局事务开启:TM 向 TC 发起全局事务开启请求,TC 生成全局唯一的 XID(Transaction ID)作为该全局事务的标识符并返回给 TM。XID 是整个分布式事务的核心标识,将贯穿整个调用链路。
README.md:69-77 详细描述了 XID 的生成与作用。
步骤 2 - XID 传播:XID 通过微服务调用链进行传播。当 TM 调用其他微服务时,XID 会作为上下文信息传递给被调用方,确保所有参与的服务都能关联到同一个全局事务。
README.md:69-77 说明了 XID 在微服务调用链中的传播机制。
步骤 3 - 分支事务注册:各微服务的 RM 在执行本地事务前,会向 TC 注册当前本地事务作为全局事务的一个分支。注册信息包括 XID、分支ID、资源ID等关键数据。
README.md:69-77 定义了分支事务的注册流程。
步骤 4 - 全局事务决议:TM 根据业务执行结果,向 TC 发起全局提交或回滚请求。这是全局事务的最终决议点,决定了所有分支事务的最终命运。
README.md:69-77 描述了 TM 如何发起全局提交或回滚。
步骤 5 - 分支事务执行:TC 根据全局事务的决议,驱动所有已注册的分支事务执行提交或回滚操作。各 RM 接收指令后执行相应的本地事务操作,并向 TC 汇报执行结果。
README.md:69-77 完整说明了 TC 驱动分支事务执行的机制。
核心模块详解
模块一:事务协调者核心引擎
职责边界:TC 核心引擎负责全局事务状态机的管理、分支事务的协调调度以及事务会话的持久化。该模块不处理具体的业务逻辑,专注于事务协调的元数据管理。
关键数据结构:
- GlobalSession:全局事务会话对象,包含 XID、事务状态、创建时间、超时时间等元信息
- BranchSession:分支事务会话对象,记录分支ID、资源ID、锁信息等
- LockManager:全局锁管理器,防止并发写冲突
关键调用链:
- 接收 TM 的 Begin 请求 → 生成 XID → 创建 GlobalSession → 持久化
- 接收 RM 的 Register 请求 → 创建 BranchSession → 关联到 GlobalSession → 获取锁
- 接收 TM 的 Commit/Rollback 请求 → 遍历所有 BranchSession → 向各 RM 发送指令
README.md:61 定义了 TC 的核心职责为"维护全局和分支事务状态,驱动全局提交或回滚"。
模块二:事务管理器客户端
职责边界:TM 客户端负责全局事务边界的定义,提供事务开启、提交、回滚的 API 接口。该模块需要与业务代码集成,通过注解或编程式 API 控制事务范围。
关键 API:
- begin():开启新的全局事务,获取 XID
- commit():提交当前全局事务
- rollback():回滚当前全局事务
- getXID():获取当前上下文的 XID
关键数据结构:
- TransactionContext:事务上下文,存储 XID、事务状态等
- RootContext:线程级上下文持有者,确保 XID 在同一线程内可访问
关键调用链:
- 业务方法进入 → @GlobalTransactional 注解拦截 → 调用 TM.begin()
- TM 向 TC 发送请求 → 获取 XID → 绑定到 RootContext
- 业务方法执行 → XID 通过 RPC 传播到下游服务
- 业务方法返回 → 根据异常情况调用 TM.commit() 或 TM.rollback()
README.md:62 明确了 TM 的职责为"定义全局事务范围:开启、提交或回滚全局事务"。
模块三:资源管理器与数据源代理
职责边界:RM 负责管理分支事务所需的资源,核心功能是代理数据源,拦截 SQL 执行,实现分支事务的注册、锁管理和最终提交/回滚。
关键数据结构:
- DataSourceProxy:数据源代理,拦截 Connection 的获取
- ConnectionProxy:连接代理,拦截 SQL 执行
- PreparedStatementProxy:语句代理,记录 SQL 执行上下文
- BranchType:分支类型枚举(AT、TCC、SAGA、XA)
关键调用链:
- 业务代码获取 Connection → 返回 ConnectionProxy
- 执行 SQL → ConnectionProxy 拦截 → 解析 SQL → 记录前后镜像
- 提交本地事务前 → 向 TC 注册分支事务 → 获取全局锁
- 接收 TC 的 commit/rollback 指令 → 执行实际的提交或回滚
README.md:63 定义了 RM 的职责为"管理分支事务工作的资源,与 TC 通信注册分支事务并汇报状态"。
模块四:通信与协议层
职责边界:通信层负责客户端与服务端之间的网络通信,定义消息协议,确保事务指令的可靠传输。
关键数据结构:
- RpcMessage:RPC 消息基类,包含消息ID、类型、数据
- RegisterTMRequest/Response:TM 注册请求/响应
- RegisterRMRequest/Response:RM 注册请求/响应
- GlobalBeginRequest/Response:全局事务开启请求/响应
- BranchRegisterRequest/Response:分支注册请求/响应
关键调用链:
- 客户端启动 → 建立 Netty Channel → 向 TC 发送注册请求
- TM 调用 begin() → 封装 GlobalBeginRequest → 通过 Channel 发送
- TC 处理完成 → 封装 GlobalBeginResponse → 返回 XID
- RM 注册分支 → 封装 BranchRegisterRequest → 发送并等待确认
README.md:59-65 中描述的角色交互均依赖此通信层实现。
模块依赖关系
正在加载图表渲染器...
依赖关系说明:
-
TM 和 RM 均依赖通信层:两个客户端模块通过统一的通信层与 TC 进行交互,确保协议一致性。
-
公共模块作为基础:包含通用的数据结构、工具类和异常定义,被所有模块依赖。
-
配置模块统一管理:所有模块从配置中心读取参数,支持动态配置更新。
-
服务发现支持高可用:通信层通过服务发现机制定位 TC 集群,支持 TC 的多节点部署。
核心设计决策与取舍
决策一:独立部署的 TC 架构
选择理由:将 TC 作为独立服务部署而非嵌入应用中,可以实现事务状态的集中管理和持久化,支持跨应用的事务协调,同时便于独立扩展和运维。
已知限制:TC 成为单点故障风险,需要通过集群部署和高可用方案解决。
README.md:61 中 TC 的职责定义支撑了这一架构决策。
决策二:XID 作为全局唯一标识
选择理由:XID 作为全局事务的唯一标识,贯穿整个调用链,确保所有分支事务能够准确关联到同一个全局事务。这种设计简化了事务上下文的传播机制。
实现方式:XID 通常通过 RPC 框架的隐式传参机制或 HTTP Header 进行传播。
README.md:69-77 详细描述了 XID 的生成与传播机制。
决策三:两阶段提交协议
选择理由:采用标准的两阶段提交(2PC)协议,第一阶段准备(注册分支),第二阶段提交或回滚。这种模式保证了事务的原子性和一致性。
已知限制:同步阻塞可能导致资源锁定时间较长,需要通过超时机制和异步优化缓解。
README.md:69-77 中描述的生命周期流程体现了两阶段提交的设计。
决策四:多模式支持(AT/TCC/SAGA/XA)
选择理由:不同业务场景对一致性、性能、侵入性的要求不同,提供多种事务模式可以让用户根据实际需求选择最合适的方案。
模式对比:
- AT 模式:无侵入,高性能,适合大多数场景
- TCC 模式:强一致,需要业务代码实现三个接口
- SAGA 模式:长事务,适合流程编排场景
- XA 模式:强一致,依赖数据库 XA 支持
README.md:47-55 中对分布式事务的定义为多模式支持提供了理论基础。
决策五:全局锁机制
选择理由:在 AT 模式下,通过全局锁防止分布式环境下的写写冲突,确保数据一致性。全局锁由 TC 统一管理,RM 在执行本地事务前需要获取锁。
已知限制:全局锁可能引入额外的等待时间,需要合理设置锁等待超时。
README.md:63 中 RM 的资源管理职责包含锁的获取与释放。
技术选型表格
| 技术/组件 | 用途 | 选型理由 | 替代方案 |
|---|---|---|---|
| Netty | 网络通信框架 | 高性能、异步事件驱动、支持自定义协议 | gRPC、Dubbo |
| Protobuf | 序列化协议 | 高效的二进制序列化,跨语言支持 | JSON、Kryo |
| Database | 会话存储 | 关系型数据库提供 ACID 保障,便于查询和管理 | Redis、文件系统 |
| Redis | 锁存储与缓存 | 高性能内存存储,支持分布式锁 | Database、Etcd |
| Spring | 集成框架 | 广泛的生态支持,便于与业务代码集成 | Guice、手动管理 |
| SPI | 扩展机制 | 灵活的插件化架构,支持自定义扩展 | Spring Bean |
| Log4j2/Logback | 日志框架 | 高性能日志记录,支持异步输出 | Java Util Logging |
| JUnit | 单元测试 | 成熟的测试框架,支持断言和 Mock | TestNG |
关键配置与启动流程
TC 服务端配置要点
TC 服务端需要配置事务会话存储模式、锁存储模式、网络端口等核心参数。生产环境推荐使用数据库存储模式以确保数据持久化。
核心配置项:
- store.mode:存储模式
- store.db.type:数据库类型
- server.port:服务端口
- server.undo.log.save.days:Undo 日志保留天数
TM/RM 客户端配置要点
客户端需要配置 TC 集群地址、应用名称、事务分组等参数,确保能够正确连接到 TC 并参与分布式事务。
核心配置项:
- seata.tx-service-group:事务分组名称
- seata.service.vgroup-mapping:事务分组到 TC 集群的映射
- seata.registry.type:注册中心类型
- seata.config.type:配置中心类型
启动流程
- TC 启动:加载配置 → 初始化存储 → 启动 Netty Server → 注册到注册中心
- TM/RM 初始化:加载配置 → 连接注册中心发现 TC → 建立 Netty Channel → 向 TC 注册
README.md:57-65 中定义的角色职责决定了各组件的启动顺序和依赖关系。
