Skip to content

20231213

Xiangkun Yin edited this page Dec 13, 2023 · 3 revisions

Seata Go Saga 开发任务制定

Q&A

Q: 是否要参照 remove spring #6017 基础上进行 seata-go 的开发?

A: seata-go 任务是按照功能进行划分,可以参照当前 2.x 分支的实现。#6017 也会尽早合并。

Q: 存储部分是否需要用 ORM 框架来实现,还是也是用 sql 模版的方式?

A: Saga 存储部分逻辑比较固定,ORM 一般适用于快速迭代、动态性强的场景,根据之前 Java 的经验,使用 ORM 会有一定的性能损失。故还是采用和 Java 相同的实现策略。

Notes

  • 尽量参考 Java 的文件结构,方便后续更改的对齐。
  • 开发时考虑接口的扩展性,比如 Saga 存储目前只有 db 形式,后续可能会实现 file 或 memory 形式。Parser 除了当前 JSON 版的实现,后续也有可能有 YAML 的需求。

会议文档

初期是快速迭代出项目的原型,可以参照 Java 的文件结构,用少量的代码覆盖到尽可能多的模块和代码文件。

0. 脚手架

经会议讨论,这部分开发需要对 seata-go 项目比较熟悉的同学来做,初步决定由 @wt-better, @luky116 完成。

  • 理解现有 seata-go 项目的结构,写一下 Saga 模式的初始化代码(比如在 client.go 中调用 InitSaga )。
  • 编写 Saga 模式的入口(增加 StateMachineEngine 接口和实现)
  • 为各个功能模块创建目录和代码文件,具体逻辑不用实现。
  • 编写 README.md,用文档来描述脚手架的模块划分。

1.1 状态机语言 - statelang

状态机语言是 0-依赖的一个模块,应该作为迁移开发的第一个部分。

领域模型 - domain

这部分工作主要是在 go 的相应文件夹下定义以下结构体

  • StateMachine
  • State
  • StateMachineInstance
  • StateInstance
  • TaskState
  • ServiceTaskState

在原型开发阶段,我们可以先专注于实现 ServiceTask 一种类型状态,因为其是状态机最核心的状态,完成 ServiceTask 的解析、处理,基本可以覆盖到各个模块的功能。

JSON 解析 - parser

依据领域模型需要实现的状态,实现对应的 JSON parser。

1.2 状态机配置

Java 中用户为状态机配置,需要使用 spring.xml 或者用代码构建一个 StateMachineConfig,在 go 中我们需要为用户提供一个非代码方式来定义状态机配置,参考其它模式 go 的实现。

状态机配置模块依赖了大量的子功能模块,后续开发相应功能时再在状态机配置中补充代码。比如,状态机配置依赖 ExpressionFactoryManager,那么先不用写相关方法,等到做表达式部分的时候再在配置中添加对应模块初始化代码。

  • 状态机配置接口 - StateMachineConfig
  • 默认实现 - DefaultStateMachineConfig

2.1 DB 存储部分

存储依赖 1.1 领域模型和 1.2 状态机配置。这个部分工作量集中在写 SQL 模版上,具体参考 seata-engine-store 模块。

  • 状态机定义(JSON)存储 - StateLangStore
  • 状态日志存储 - StateLogStore
  • 数据库配置实现 - DbStateMachineConfig

2.2 服务执行

目前在 Java 代码中,我们视 spring bean 的一个方法作为服务的实现。对于 go 而言,我们需要使用一个替代方案,比如将 RPC 调用视作一个服务。

  • 在 seata-go 中实现 RPC 类型的 ServiceType
  • 在 seata 中也需要实现 RPC 类型的服务

2.3 表达式集成

Java 目前默认使用 SpEL 作为表达式语言。在 go 中,我们可以集成 CEL 作为支持的表达式类型。

  • 实现 ExpressionFactoryManager, ExpressionResolver 等表达式相关组件。
  • 在 seata-go 中实现 CEL 类型的 Expression
  • 在 seata 中也需要实现 CEL 类型的 Expression

3 流程顺序执行

根据 Java 的实现,我们还是采用事件驱动的架构,对状态实现 handler 和 router。

  • seata-saga-processctrl 模块,状态机流程执行的基础组件
  • engine.pcext 包下所有内容,注意状态相关的 handler 和 router 先只需要实现 ServiceTask

注意在实现这部分的过程中,可以先忽略掉 Java 代码中对全局、分支事务的处理,先专注于流程的执行,事务放在后续的开发任务中实现。

4.1 补偿

对状态机进行逆向补偿,目前 Java 实现补偿的有一部分逻辑位于 CompensateTriggerHandler 中,在 go 中我们先不实现 CompensateTrigger 状态,把这部分逻辑外提即可。

4.2 前向

对状态机进行前向操作,这部分代码集中在 StateMachineEngine#forward 中。

5 事务

这部分任务补充在流程执行的过程中所有和事务相关的处理,包括状态上报、驱动提交或回滚等。可以参考 Java seata-saga-tm,seata-saga-rm, InSagaBranchHandlerInterceptor 的实现。

这个任务是 Saga 和 seata-go 核心耦合的部分,需要了解 seata-go 事务相关的 API。


6 补全状态

在第 5 阶段后,项目应呈现的是一个可用态,后续我们需要补全其余支持的状态,不光是补全领域模型,还需要补全对应的 handler,router 以及其它相关逻辑代码。

Clone this wiki locally