如何将Saga建模为状态机

51CTO 2021-08-20

状态机saga事务管理

2887 字丨阅读本文需 12 分钟

在微服务架构中,单个服务内的事务通常使用ACID事务来提供数据一致性。

本文描述了在微服务系统中管理分布式和长时间运行的事务的架构和概念框架。作者发表此文旨在与开发社区分享经验,表达对事件驱动架构的热情,并促进对复杂事件处理分布式系统的讨论兴趣。

微服务在其真正的场景中是一个分布式系统。一个事务被分发到多个服务,这些服务被顺序或并行调用以完成整个事务。在微服务架构中,单个服务中的事务使用ACID事务来提供数据一致性。然而,面临挑战在于处理跨多个服务的事务,在某些情况下需要很长时间才能完成。在这种情况下,应用程序必须使用复杂的机制来管理事务。而ACID是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务是正确可靠的,所必须具备的四个特性:原子性、一致性、隔离性、持久性。

考虑一个使用微服务架构实现的航空公司航班座位预订简单的场景。在这个场景中,一个微服务来锁定预订座位,另一个微服务接受付款,还有一个微服务在付款之后解锁并分配席位,每个微服务都实现一个本地事务。旅客要成功完成航班预订流程,必须完成所有三个步骤。如果任何一个步骤失败,则必须回滚之前完成的所有步骤。由于整体事务的边界跨越多个服务和数据库,因此被认为是一个分布式事务。

考虑通过微服务方法实现另一个订单实现场景。工作流事务从订单服务开始,首先创建订单,随后采用另一个服务进行付款,接下来为交易创建发票,然后进行发货,最后交付订单并完成工作流,并循环执行每个本地事务。这里的订单处理本质上是分布式的,完成工作流程可能需要几天到几周的时间。这样的事务可以称为长时间运行的事务,因为不能使用传统的ACID事务语义一次性执行所有步骤。

随着微服务架构的出现,分布式事务管理存在两个关键问题:

为了解决这些问题并提供有效的事务管理能力,可以采取两种方法:一是两阶段提交(2PC) ;二是Saga。

(1)两阶段提交(2PC)

保持跨多个服务的数据一致性的传统方法是使用分布式事务,其事实标准是两阶段提交(2PC)。两阶段提交(2PC)  确保事务中的所有参与者或者提交或者回滚。它分为两个阶段工作;阶段1称为准备阶段,控制节点询问所有参与节点是否准备好提交;阶段2称为提交阶段,如果所有节点都回答是肯定的,则控制节点要求它们提交,否则回滚。

尽管两阶段提交(2PC)可以帮助在分布式系统中提供事务管理,但它也会成为单点故障,因为事务的责任落在了协调器上,并且这种协调器的典型实现本质上是同步的,这会导致减少未来的吞吐量。因此,两阶段提交(2PC)还存在以下不足:

(2)Saga

为了解决在微服务架构中维护数据一致性这一更复杂的问题,应用程序必须使用基于松耦合异步服务概念的不同机制。这就是Saga发挥重要作用的地方。

Saga是一种架构模式,它提供了一种优雅的方法来实现跨多个服务的事务,在本质上是异步和反应式的。因此,Saga可以定义为事件驱动的本地事务序列,其中每个本地事务更新数据库,并发布命令或事件以触发Saga中的下一个本地事务。如果本地事务因为违反业务规则而失败,那么Saga将执行一系列补偿事务,这些补偿事务将撤消先前本地事务所做的更改。

Saga实现确保执行所有事务或撤消所有更改,从而提供原子性保证。将Saga设计为状态机模型将提供处理隔离的对策。

使用微服务架构,单个业务流程将多个微服务聚合在一起以提供整体解决方案。使用微服务架构实现ACID(原子性、一致性、隔离性、持久性)事务非常困难,并且在某些情况下是不可能的。

例如,在以上提到的航班座位预订场景中,具有预订座位功能的微服务无法实现支付数据库的锁定,因为它在大多数情况下可能是外部服务。但是仍然需要某种形式的事务管理,这种事务被称为BASE事务:基本可用、软状态和最终一致。

必须采取补偿措施来恢复作为事务一部分发生的任何事情。以下是Saga如何为航班预订座位场景图:

当Saga的一个步骤由于违反业务规则而失败时,Saga必须通过执行补偿事务撤消先前步骤所做的更新。假设Saga的第(n 1)个交易失败,则必须撤销之前n个事务的影响。

从概念上来说,每个步骤Ti都有一个相应的补偿事务Ci,它可以消除Ti的影响。为了消除前n个步骤的影响,Saga必须以相反的顺序执行每个Ci。如图所示,其步骤顺序为T1…Tn、Cn…C1。

在这一示例中,Tn 1步骤失败,这需要撤消T1…Tn步骤。Saga以与远期事务相反的顺序执行补偿事务:Cn…C1。Cis测序的机制与Tis测序没有任何区别。Ci的完成必须触发Ci-1的执行。

下表显示了Saga在航班座位预订中每个步骤的补偿事务,其三个步骤被称为补偿事务,因为它们之后是可能失败的步骤。在此需要注意的是,并非所有步骤都需要补偿事务。

Saga模式中还有另外两种事务类型;一个是Pivot事务,就像Saga中的一个成功/失败点。如果Pivot事务提交,则Saga将一直运行到结束。另一个是Retryable事务,跟随Pivot事务并保证事务成功。

Saga保证以下两种结果之一: Saga中的所有请求或者都成功完成,或者执行一部分请求及其补偿请求。而请求和补偿请求都需要遵循一定的原则:

Saga执行协调器(SEC)是实现成功的Saga流程的核心组件。Saga协调可在以下方面实施:

尽管Saga编排是简单且可靠的基于事件的通信,但它只能处理简单用例,并且存在一些限制,这使其无法成为管理分布式事务的理想选择。而基于编排的Saga难以理解,经常会产生循环依赖,并且Saga参与者之间存在紧密耦合的风险。

正如Saga“协调”模式所暗示的那样,有一个单独的协调器组件负责管理整个流程工作流。在使用编制时可以定义一个协调器类,它的唯一职责是告诉Saga参与者要做什么。Saga协调器使用命令/异步回复式交互与参与者进行通信。为了执行Saga步骤,它会向参与者发送命令消息,告诉它要执行什么操作。在Saga参与者执行操作后,它会向协调器发送回复消息。然后协调器处理这一消息并确定下一步要执行的Saga步骤。

上图显示了航班座位预订采用Saga的基于协调器的过程。Saga由Saga协调器组件编排,该组件使用异步请求/响应调用Saga参与者。Saga协调器跟踪进程并通过命令组件向Saga参与者发送命令操作,例如座位锁定服务(Seat  Blocking Service)和付款服务(Payment  Service),并通过事件处理器从其回复通道读取回复消息,然后确定下一个步骤,采用Saga协调器预订航班座位的步骤如下:

(1)FrontEnd UI向Saga协调器发送座位预订请求。

(2)Saga协调器启动一个新的工作流并向座位锁定服务(Seat Blocking Service)发送一个座位锁定命令(Seat Blocking  Command)。

(3)座位锁定服务(Seat Blocking Service)处理命令并回复一个座位锁定事件(Seat Blocked Event)。

(4)Saga协调器触发工作流中的下一个动作,并向付款服务(Payment Service)发送付款请求命令(Payment Request  Command)。

(5)付款服务(Payment Service)回复付款成功事件(Payment Success Event)。

(6)Saga协调器然后向座位分配服务(Seat Allocation Service)发送一个座位分配命令(Seat Allocation  Command)。

(7)座位分配服务(Seat Allocation Service)回复一个座位分配事件(Seat Allocated Event)。

(8)Saga协调器结束事务并完成工作流。

但是,如果座位锁定服务、付款服务或座位分配服务中任何一个步骤失败,Saga航班预订的场景可能会失败。为了有效地管理工作流并处理故障,建议将Saga建模为状态机,因为它描述了所有可能的场景,并让协调器确定需要执行的操作。

将Saga协调器建模为状态机是一种有效的方式,不仅可以管理分布式事务,还可以支持长时间运行的事务。状态机由一组状态和一组由事件触发的状态之间的转换组成。每个转换都可以有一个动作,对于Saga来说,它是一个Saga参与者的调用。

状态之间的转换由Saga参与者执行的本地事务的完成触发。当前状态和本地事务的特定结果决定了状态转换以及要执行的操作。因此,使用状态机模型可以更轻松地设计、实现和测试Sagas。

上图突出显示了Saga航班预订的状态机模型。该状态机由许多状态和转换组成,其中包括以下内容:

最后,Saga工作流可以重新设计为Saga状态机。Saga协调器链接到一个状态机,它负责通过状态管理器API管理事务状态。除此之外,它还负责将事务状态存储在持久数据存储设备中,以确保发生系统故障时的恢复。

因此,Saga状态机有责任或者完成所有事务,或者使系统处于已知状态,以便它可以确定可能执行下一个动作状态或补偿活动的顺序,无论发生的事务是分布的还是长期的。

可以执行此类实现的几个潜在用例:

(1)订单管理系统

(2)结算交易。

如果组织正在设计和构建编排器驱动的Saga以支持分布式和长时间运行的事务,则建议遵循以下准则:

原文标题:Modeling Saga as a State Machine,作者:Rohit Singh

【51CTO译稿,合作站点转载请注明原文译者和出处】

【编辑推荐】

来源:51CTO李睿

免责声明:凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处本网。非本网作品均来自其他媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如您发现有任何侵权内容,请依照下方联系方式进行沟通,我们将第一时间进行处理。

0赞 好资讯,需要你的鼓励
来自:51CTO
0

参与评论

登录后参与讨论 0/1000

为你推荐

没有更多了