Skip to content

Seata‐go summar code ‐ saga design

JayLiu edited this page Jan 20, 2024 · 1 revision

在seata-go中实现saga事务模式 项目背景

成员

项目基本需求

Saga模式是SEATA提供的长事务解决方案 ,在Saga模式中 ,业务流程中每个参与者都提交本地事

务 , 当出现某一个参与者失败则补偿前面已经成功的参与者 ,一 阶段正向服务和二阶段补偿服务都由 业务开发实现。Seata-go中当前没有支持saga模式 ,希望后面参考Java版本的实现能将该功能支持 上。

相关issue:https://github.com/seata/seata-go/issues/43

  • 设计seata-go中saga模式的实现 ,并保证saga模式能完整运行

  • seata-go能解析现在seata-java侧的状态机生成的编排文件

  • 给seata-go设计并提供简单易用的Saga模式使用入口

理论基础

补偿事务与Saga

对数据有强一致性需求时 ,业务层上会采取两阶段提交(更具体的TCC模式)这样的分布式事务方案- 另一些场景下 ,我们并不需要这么强的一致性 ,那就只需要保证最终一致性就可以了。此外 ,一些业 务流程长 ,事务边界太长影响性能;无法保证其他业务方也满足TCC开发模式。

实际开发中提出补偿事务的概念 ,基于补偿事务的saga也作为长事务的解决方案

关于saga具体细节可参考:

Seata邻域模型

Seata邻域模型可用Seata官网下图描述

image

其中涉及的角色有三个:

• 事务管理者(TM):创建和决议事务结果的实体,一般集成于业务调用链路的上游.

• 资源管理者(RM):管理资源的实体,一般情况下等同于微服务中的提供方(provider),管理其所在服务 中的资源

◦ Saga模型中和TM集成在一起

• 事务协调者(TC):用于2pc方式的事务模式统一协调事务的实体(SAGA除外) Seata将global transaction分解为多个Branch Transaction ,更多细节可见官网

项目相关仓库

结合seata sample开发可以基于go 1.18之后的workspace特性实现 ,具体可见seata sample中说明。

相关技术点与可行性讨论

Saga

以下引用自官网SEATA对于Saga模式的定义

Saga模式是SEATA提供的长事务解决方案 ,在Saga模式中 ,业务流程中每个参与者都提交本地事

务 , 当出现某一个参与者失败则补偿前面已经成功的参与者 ,一 阶段正向服务和二阶段补偿服务都由 业务开发实现。

理论基础: Hector & Kenneth 发表论文 Sagas ( 1987)

image

不同于2PC ,Saga是一类用于实现长事务的分布式事务模型。可应用Saga的业务 ,通常可以划分为多 个阶段 ,并用一个状态机描述在分支事务成功/失败的流转。

本人在实习时曾遇到涉及金融结算且涉及多个微服务的场景 , 当时实现事务的策略是:首先定义业务 在涉及到的各个微服务返回成功/失败时状态流转 ,通过存储持久化事务状态 ,针对状态设置相应的补 偿机制。

Method Invoker

  • 主要用于状态执行时调用接入方式实现的业务代码 ,难点主要在于go实现并没有java语言那样方便 和一些语言特点

  • 本人在实习时曾有过基于使用的微服务开发框架以及idl共同实现方法代理的经验

  • 对于当前这个问题 ,已经调研到的思路有使用反射+手动代理的方式实现 ,关于反射调用method的 方法demo

Evalu ator

  • 状态机在路由时需要根据eval结果决定下一个状态 ,困难点在于golang对象体系没有java灵活 - 对于这个问题 ,调研到golang生态有一些开源的eval库

Docker

  • 主要用于saga sample服务部署的模拟构建。
  • 本人在日常学习工作中经常使用docker配置环境 ,保证测试开发环境的可迁移 ,同时也避免不同工 作环境配置之间污染的风险。本人在实习过程中 ,也有过资源部署等知识使用+学习经历-

项目详细方案

Saga Life Cycle

接入业务方选择服务担任TM ,并通过StateMachineEngine开启事务 ,本次实现主要针对同步方式的 实现(Java项目可以支持同步、异步方式)。主要任务如下

  1. 创建执行上下文ProcessContext。
  2. 向TC开启全局事务 ,并返回xid。
  3. 将state持久化到本地( DB)。
  4. 向EventBus中发布Event。

状态机运行起来后 ,流程处理主要分为两个部分:state处理以及路由(状态转移)

  1. State处理

a. 根据状态选择合适的processor

b. 根据state执行processor ,主要是serviceTask的处理

i. 根据对象名和方法名创建serviceInvoker

ii. serviceInvoker代理调用state中定义的方法

c- 执行相应的增强逻辑

i- preProcess注册分支事务 ,本地db记录事务

ii- postProcess更新本地事务状态 ,向TC报告执行结果

  1. 路由

a. state中寻找next节点

b. 执行expression找到下一个state

整体实现思路

  1. state lang解析器 ,能够解析seata-java侧状态机生成的编排文件。

a. 针对state lang中不同类型的state需要衍生设计不同的domain , 当前计划支持最主要的语法解 析 ,保证实现基本可用。

  1. 实现状态机引擎 ,支持按照编排文件流转的语义

a. 其中最重要的是状态的执行 ,这里牵涉到较多需要解决的技术难题

b. 状态机的流转是另一大问题 ,在seata-java中的策略是路由

Statelang的解析

项目要求的state lang本身是一个json ,区别在于可以表示状态语义。这里可以参考seata java state lang的实现 ,分别设计domain和parser。

  • domain设计一系列对象用于承载不同的状态和状态机。state lang中所涉及的状态和行为可见 seata sagaState language referance一节。
  • parser主要负责将json解析后的原始中间结果 ,分别利用上述domain加载状态文件中各个state的 行为和route等信息。json中间结果解析可以使用go生态一些较为成熟的解析库。

状态机引擎

这里可以引用seata博客中关于saga状态机流转的描述

image

  • seata的saga实现中 ,状态机的驱动基于事件。消费端从Event Queue取出路由消息获取对应状 态 ,执行状态中定义的行为。

  • 接入业务方担任TM ,启动状态机是会申请全局xid ,并记录状态机实例启动事件到本地数据库。

  • 分支事务会条用seata server注册分支事务 ,生产对应的branchId ,记录状态实例的开始和结束到 本地数据库 ,并向seata server上报。在seata-java中 ,这部分具体实现集中在通过inceptor执行 preProcess和postProcess。

状态机引擎设计也可以参考seata官网博客的描述

• Eventing:实现Event Driven ,支持事件的push和consume

• ProcessController :具体state的process和route由上层实现 ,该层实现基于Eventing驱动状态流 转

• StateMachineEngine :提供ProcessController中所需要的、具体的Processor Handler和Router Handler。提供Interceptor逻辑、config逻辑等

◦ state的process需要根据配置的方法名实现method invoker ,在可行性讨论中有关于这点的讨 论

◦ route需要实现根据表达式决定next state ,go生态有关于eval的开源实现 ,可以借鉴使用

Saga sample的实现

测试是一个附加的功能点 ,seata-go-sample中需要提供关于saga事务模型的样例。测试案例可以参 考选取saga官网中使用的例子。相关状态机工具只需要继续沿用java实现即可。

image

测试关注几个要点:

  1. 能否解析成功state lang文件 ,并成功加载到状态机上?
  2. 状态机的流转能否遵从状态文件的约束?各状态的对应行为能否按要求执行?

实现测试需要完成的工作:

  1. 利用docker等工具实现微服务场景的模拟部署
  2. seata服务部署相关配置
  3. sample例子接入业务代码的实现

排期

本人当前研一下 ,预期每周可以保证分出20小时投入到项目开发。对于开源世界本人向往已久 ,非 常希望借此机会做出一份贡献。对分布式相关技术既是本人当前兴趣所在 ,同时也是本人研究方向, 此前经历也和seata社区的目标非常吻合 ,也希望之后能参与更多seata社区建设。

项目开发阶段(07月01日-08月20日)

0 state lang解析

0 domain设计与实现

0 parser解析状态机文件

  • 状态机的搭建

0 Eventing层事件驱动的设计与实现

0 ProcessController结合Eventing搭建状态机流转

  • 状态机引擎实现 ,主要实现ProcessController中processor和router的载体

  • 实现ProcessHandler ,执行状态定义的行为

  • 实现RouteHandler ,根据当前state执行后结果决定next state

0 seata邻域模型相关约束的实现

  • 状态机的初始化与全局id的申请

  • 分支事务的注册与状态在local db的持久化

  • 状态机的配置、加载等功能

0 Saga sample的实现

  • 测试环境搭建

  • 服务的部署与事务模型的配置

0 sample的选择与配置

0 sample业务代码实现

项目验收及后续工作(08月21日-09月30日)

Ref

Seata官网资料

Seata邻域模型

Saga

Saga博客

• Saga理论相关 ◦ Chris

paper

• 其他参考资料

原理解读

模式实现分析其他参考

Clone this wiki locally