微服务架构 | 11. 分布式事务

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 分布式事务是指事务的参与者、支持事务的服务器、资源服务器及事务管理器分别位于分布式系统的不同节点上;

前言

参考资料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》

分布式事务是指事务的参与者、支持事务的服务器、资源服务器及事务管理器分别位于分布式系统的不同节点上;


1. 基础知识

1.1 分布式事务问题的理论模型

1.1.1 X/Open 分布式事务模型(XA 协议)

  • X/Open DTP 包含以下三种角色:

    • AP:Application,表示应用程序;
    • RM:Resource Manager,表示资源管理器,比如数据库;
    • TM:Transaction Manager,表示事务管理器,一般指事务协调者,负责协调和管理事务,提供 AP 编程接口或管理 RM 。可以理解为 Spring 中提供的 Transaction Manager;

分布式事务处理 DTP 模型
-TM 和多个 RM 之间的事务控制,是基于 XA 协议(XASpecification)来完成的。XA 协议是 X/Open 提出的分布式事务处理规范,也是分布式事务处理的工业标准,它定义了 xa_ 和 ax_ 系列的函数原型及功能描述、约束等。目前 Oracle、MySQL、DB2 都实现了 XA 接口,所以它们都可以作为 RM;

事务执行流程

1.1.2 两阶段提交协议

  • 两阶段:

    • 事务的准备阶段:事务管理器(TM)通知资源管理器(RM)准备分支事务,记录事务日志,并告知事务管理器的准备结果;
    • 事务的提交或者回滚阶段:如果所有的资源管理器(RM)在准备阶段都明确返回成功,则事务管理器(TM)向所有的资源管理器(RM)发起事务提交指令完成数据的变更。反之,如果任何一个资源管理器(RM)明确返回失败,则事务管理器(TM)会向所有资源管理器(RM)发送事务回滚指令;
  • 优点:简单,降低事务提交失败率;
  • 缺点:同步阻塞(对于任何一次指令都必须要有明确的响应才能继续进行下一步)、过于保守(任何一个节点失败都会导致数据回滚);

两阶段提交协议执行流程

1.1.3 三阶段提交协议

  • 三阶段:

    • CanCommit(询问阶段):事务协调者向参与者发送事务执行请求,询问是否可以完成指令,参与者只需要回答是或者不是即可,不需要做真正的事务操作,这个阶段会有超时中止机制;
    • PreCommit(准备阶段):事务协调者会根据参与者的反馈结果决定是否继续执行,如果在询问阶段所有参与者都返回可以执行操作,则事务协调者会向所有参与者发送 PreCommit 请求,参与者收到请求后写 redo 和 undo 日志,执行事务操作但是不提交事务,然后返回 ACK 响应等待事务协调者的下一步通知。如果在询问阶段任意参与者返回不能执行操作的结果,那么事务协调者会向所有参与者发送事务中断请求;
    • DoCommit(提交或回滚阶段):这个阶段也会存在两种结果,仍然根据上一步骤的执行结果来决定 DoCommit 的执行方式。如果每个参与者在 PreCommit 阶段都返回成功,那么事务协调者会向所有参与者发起事务提交指令。反之,如果参与者中的任一参与者返回失败,那么事务协调者就会发起中止指令来回滚事务;
  • 优点:可以尽早发现无法执行操作而中止后续的行为;在准备阶段后,事务协调者和参与者都引入了超时机制;基于超时机制来避免资源的永久锁定;
  • 缺点:一旦超时,仍然可能出现数据不一致的情况;

三阶段提交协议执行流程

1.2 分布式事务的两个理论模型

1.2.1 CAP 定理

  • 《微服务架构 | 3. 注册中心与服务发现》中讲解的一样,指在分布式系统中不可能同时满足一致性(C:Consistency)、可用性(A:Availability)、分区容错性(P:Partition Tolerance)这三个基本需求,最多同时满足两个;

    • C:数据在多个副本中要保持强一致,比如前面说的分布式数据一致性问题;
    • A:系统对外提供的服务必须一直处于可用状态,在任何故障下,客户端都能在合理的时间内获得服务端的非错误响应;
    • P:在分布式系统中遇到任何网络分区故障,系统仍然能够正常对外提供服务;
  • 网络分区:不同节点分布在不同的子网络中时,在内部子网络正常的情况下,由于某些原因导致这些子节点之间出现网络不通的情况,导致整个系统环境被切分成若干独立的区域,这就是网络分区;
  • 在分布式系统中,不会选择 CA,而是 APCP

    • AP:放弃了强一致性,实现最终的一致,是很多互联网公司解决分布式数据一致性问题的主要选择;
    • CP:放弃了高可用性,实现强一致性。前面提到的两阶段提交和三阶段提交都采用这种方案。可能导致的问题是用户完成一个操作会等待较长的时间;
    • CA:无法同时做到保证数据一致性和可用,要保证数据一致性可能要拒绝客户端请求,除非网络百分百可靠;

1.2.2 BASE 理论

  • BASE 理论是由于 CAP 中一致性 C可用性 A不可兼得而衍生出来的一种新的思想,BASE 理论的核心思想是通过牺牲数据的强一致性来获得高可用性。它有如下三个特性;

    • Basically Available(基本可用):分布式系统在出现故障时,允许损失一部分功能的可用性,保证核心功能的可用;
    • Soft State(软状态):允许系统中的数据存在中间状态,这个状态不影响系统的可用性,也就是允许系统中不同节点的数据副本之间的同步存在延时;
    • Eventually Consistent(最终一致性):中间状态的数据在经过一段时间之后,会达到一个最终的数据一致性;
  • BASE 理论并没有要求数据的强一致,而是允许数据在一段时间内是不一致的,但是数据最终会在某个时间点实现一致;
  • 在互联网产品中,大部分都会采用 BASE 理论来实现数据的一致,因为产品的可用性对于用户来说更加重要;
  • 举个例子,在电商平台中用户发起一个订单的支付,不需要同步等待支付的执行结果,系统会返回一个支付处理中的状态到用户界面。对于用户来说,他可以从订单列表中看到支付的处理结果。而对于系统来说,当第三方的支付处理成功之后,再更新该订单的支付状态即可。在这个场景中,虽然订单的支付状态和第三方的支付状态存在短期的不一致,但是用户却获得了更好的产品体验;

1.3 分布式事务问题的常见解决方案(事务模式)

在互联网场景中更多采用柔性事务,所谓的柔性事务是遵循 BASE 理论来实现的事务模型,它有两个特性:基本可用、柔性状态;

1.3.1 TCC 补偿型方案

  • TCC(Try-Confirm-Cancel)是一种比较成熟的分布式数据一致性解决方案,它实际上是把一个完整的业务拆分为如下三个步骤:

    • Try:这个阶段主要是对数据的校验或者资源的预留(冻结资源);
    • Confirm:确认真正执行的任务,只操作 Try 阶段预留的资源(消耗冻结资源);
    • Cancel:取消执行,释放 Try 阶段预留的资源(解冻资源);
  • 其实 TCC 是一种两阶段提交的思想,第一阶段通过 Try 进行准备工作,第二阶段 Confirm/Cancel 表示 Try 阶段操作的确认和回滚;
  • 在一些特殊情况下,服务并没有收到 TCC 事务协调器的 Cancel 或者 Confirm 请求时,可以记录一些分布式事务的操作日志,保存分布式事务运行各个阶段和状态,以实现一致性;
  • TCC 服务支持接口调用失败发起重试,所以 TCC 暴露的接口都需要满足幂等性;

TCC 方案执行流程

1.3.2 基于可靠性消息的最终一致性方案

  • 基于可靠性消息的最终一致性是互联网公司比较常用的分布式数据一致性解决方案;
  • 它主要利用消息中间件(Kafka、RocketMQ 或 RabbitMQ)的可靠性机制来实现数据一致性的投递;
  • 在某些场景中可以牺牲数据的一致性在短时间内不要求实时性,所以可以采用基于可靠性消息的最终一致性方案来保证最终的数据一致性;
  • 在消费者没有向消息中间件服务器发送确认时,这个消息会被重复投递,确保消息的可靠性消费;
  • RocketMQ 使用事件消息模型解决事务问题,其核心是事务回查,主要逻辑如下:

    • 生产者发送一个事务消息到消息队列上,消息队列只记录这条消息的数据,此时消费者无法消费这条消息;
    • 生产者执行具体的业务逻辑,完成本地事务的操作;
    • 接着生产者根据本地事务的执行结果发送一条确认消息给消息队列服务器,如果本地事务执行成功,则发送一个 Commit 消息,表示在第一步中发送的消息可以被消费,否则,消息队列服务器会把第一步存储的消息删除;
    • 如果生产者在执行本地事务的过程中因为某些情况一直未给消息队列服务器发送确认,那么消息队列服务器会定时主动回查生产者获取本地事务的执行结果,然后根据回查结果来决定这条消息是否需要投递给消费者;
    • 消息队列服务器上存储的消息被生产者确认之后,消费者就可以消费这条消息,消息消费完成之后发送一个确认标识给消息队列服务器,表示该消息投递成功;

RocketMQ 的事件消息模型

1.3.3 最大努力通知型

  • 基于可靠性消息的最终一致性方案类似,适用于对数据一致性要求不高的场景;
  • 在支付服务没有返回一个消息确认时,支付宝会不断进行重试,直到一个消息确认或达到最大重试次数;

最大努力通知型

1.3.4 AT 模式

  • AT 模式是 Seata 最主推的分布式事务解决方案,它是基于 XA 演进而来的一种分布式事务模式。分为三大模块:TM、RM 和 TC(与XA不同)。其中:

    • TM 事务管理器:负责向 TC 注册一个全局事务,并生成一个全局唯一的 XID。作为 Seata 的客户端与业务系统集成;
    • RM 数据库资源:在业务层面通过 JDBC 标准的接口访问 RM 时, Seata 会对所有请求进行拦截。作为 Seata 的客户端与业务系统集成;
    • TC 事务协调器:每个本地事务进行提交时,RM 都会向 TC 注册一个分支事务。作为 Seata 的服务器独立部署;
  • AT 模式和 XA 一样,也是一个两阶提交事务模型;

Seata 的 AT 事务模式

1.3.5 Saga 模式

  • Saga 模式又称为长事务解决方案,主要描述的是在没有两阶段提交的情况下如何解决分布式事务问题;
  • 其核心思想是:把一个业务流程中的长事务拆分为多个本地短事务,业务流程中的每个参与者都提交真实的提交给该本地短事务,当其中一个参与者事务执行失败,则通过补偿机制补偿前面已经成功的参与者;
  • Saga 的机制相关详情请见笔者的另一篇文章:《微服务架构设计模式》读书笔记 | 第4章 使用Saga管理事务

1.5 目前几种流行的分布式事务技术方案对比

名称 厂商 特点(优点) 缺点
Seata Alibaba 对业务无侵入、高性能 Seata 是工作在读未提交的隔离级别,Seata 本身存在一定的性能损耗


2. Seata

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务;它提供了 AT、TCC、Saga 和 XA 事务模式,为开发者提供了一站式的分布式事务解决方案;



相关文章
|
7天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
7天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
105 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
6天前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
87 36
微服务架构解析:跨越传统架构的技术革命
|
9天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
37 8
|
4天前
|
存储 算法 安全
分布式系统架构1:共识算法Paxos
本文介绍了分布式系统中实现数据一致性的重要算法——Paxos及其改进版Multi Paxos。Paxos算法由Leslie Lamport提出,旨在解决分布式环境下的共识问题,通过提案节点、决策节点和记录节点的协作,确保数据在多台机器间的一致性和可用性。Multi Paxos通过引入主节点选举机制,优化了基本Paxos的效率,减少了网络通信次数,提高了系统的性能和可靠性。文中还简要讨论了数据复制的安全性和一致性保障措施。
19 1
|
12天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
27 8
|
10天前
|
存储 运维 数据可视化
如何为微服务实现分布式日志记录
如何为微服务实现分布式日志记录
18 1
|
13天前
|
消息中间件 运维 Kubernetes
后端架构演进:从单体到微服务####
本文将探讨后端架构的演变过程,重点分析从传统的单体架构向现代微服务架构的转变。通过实际案例和理论解析,揭示这一转变背后的技术驱动力、挑战及最佳实践。文章还将讨论在采用微服务架构时需考虑的关键因素,包括服务划分、通信机制、数据管理以及部署策略,旨在为读者提供一个全面的架构转型视角。 ####
27 1
|
16天前
|
消息中间件 运维 Cloud Native
云原生架构下的微服务优化策略####
本文深入探讨了云原生环境下微服务架构的优化路径,针对服务拆分、通信效率、资源管理及自动化运维等核心环节提出了具体的优化策略。通过案例分析与最佳实践分享,旨在为开发者提供一套系统性的解决方案,以应对日益复杂的业务需求和快速变化的技术挑战,助力企业在云端实现更高效、更稳定的服务部署与运营。 ####
|
6天前
|
Cloud Native API 持续交付
云原生架构下的微服务治理策略与实践####
本文旨在探讨云原生环境下微服务架构的治理策略,通过分析当前面临的挑战,提出一系列实用的解决方案。我们将深入讨论如何利用容器化、服务网格(Service Mesh)等先进技术手段,提升微服务系统的可管理性、可扩展性和容错能力。此外,还将分享一些来自一线项目的经验教训,帮助读者更好地理解和应用这些理论到实际工作中去。 ####
17 0