-
Notifications
You must be signed in to change notification settings - Fork 8.8k
Seata‐go summar code ‐ saga design
-
项目导师:刘月财 luky116@apache.org
-
申请人: 陈彦辉 misterchen@mail.ustc.edu.cn
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模式使用入口
对数据有强一致性需求时 ,业务层上会采取两阶段提交(更具体的TCC模式)这样的分布式事务方案- 另一些场景下 ,我们并不需要这么强的一致性 ,那就只需要保证最终一致性就可以了。此外 ,一些业 务流程长 ,事务边界太长影响性能;无法保证其他业务方也满足TCC开发模式。
实际开发中提出补偿事务的概念 ,基于补偿事务的saga也作为长事务的解决方案
关于saga具体细节可参考:
Seata邻域模型可用Seata官网下图描述
其中涉及的角色有三个:
• 事务管理者(TM):创建和决议事务结果的实体,一般集成于业务调用链路的上游.
• 资源管理者(RM):管理资源的实体,一般情况下等同于微服务中的提供方(provider),管理其所在服务 中的资源
◦ Saga模型中和TM集成在一起
• 事务协调者(TC):用于2pc方式的事务模式统一协调事务的实体(SAGA除外) Seata将global transaction分解为多个Branch Transaction ,更多细节可见官网
-
seata sample仓库:https://github.com/seata/seata-go-samples
-
seata java仓库:https://github.com/seata/seata
结合seata sample开发可以基于go 1.18之后的workspace特性实现 ,具体可见seata sample中说明。
以下引用自官网SEATA对于Saga模式的定义
Saga模式是SEATA提供的长事务解决方案 ,在Saga模式中 ,业务流程中每个参与者都提交本地事
务 , 当出现某一个参与者失败则补偿前面已经成功的参与者 ,一 阶段正向服务和二阶段补偿服务都由 业务开发实现。
理论基础: Hector & Kenneth 发表论文 Sagas ( 1987)
不同于2PC ,Saga是一类用于实现长事务的分布式事务模型。可应用Saga的业务 ,通常可以划分为多 个阶段 ,并用一个状态机描述在分支事务成功/失败的流转。
本人在实习时曾遇到涉及金融结算且涉及多个微服务的场景 , 当时实现事务的策略是:首先定义业务 在涉及到的各个微服务返回成功/失败时状态流转 ,通过存储持久化事务状态 ,针对状态设置相应的补 偿机制。
-
主要用于状态执行时调用接入方式实现的业务代码 ,难点主要在于go实现并没有java语言那样方便 和一些语言特点
-
本人在实习时曾有过基于使用的微服务开发框架以及idl共同实现方法代理的经验
-
对于当前这个问题 ,已经调研到的思路有使用反射+手动代理的方式实现 ,关于反射调用method的 方法demo
- 状态机在路由时需要根据eval结果决定下一个状态 ,困难点在于golang对象体系没有java灵活 - 对于这个问题 ,调研到golang生态有一些开源的eval库
- 主要用于saga sample服务部署的模拟构建。
- 本人在日常学习工作中经常使用docker配置环境 ,保证测试开发环境的可迁移 ,同时也避免不同工 作环境配置之间污染的风险。本人在实习过程中 ,也有过资源部署等知识使用+学习经历-
接入业务方选择服务担任TM ,并通过StateMachineEngine开启事务 ,本次实现主要针对同步方式的 实现(Java项目可以支持同步、异步方式)。主要任务如下
- 创建执行上下文ProcessContext。
- 向TC开启全局事务 ,并返回xid。
- 将state持久化到本地( DB)。
- 向EventBus中发布Event。
状态机运行起来后 ,流程处理主要分为两个部分:state处理以及路由(状态转移)
- State处理
a. 根据状态选择合适的processor
b. 根据state执行processor ,主要是serviceTask的处理
i. 根据对象名和方法名创建serviceInvoker
ii. serviceInvoker代理调用state中定义的方法
c- 执行相应的增强逻辑
i- preProcess注册分支事务 ,本地db记录事务
ii- postProcess更新本地事务状态 ,向TC报告执行结果
- 路由
a. state中寻找next节点
b. 执行expression找到下一个state
- state lang解析器 ,能够解析seata-java侧状态机生成的编排文件。
a. 针对state lang中不同类型的state需要衍生设计不同的domain , 当前计划支持最主要的语法解 析 ,保证实现基本可用。
- 实现状态机引擎 ,支持按照编排文件流转的语义
a. 其中最重要的是状态的执行 ,这里牵涉到较多需要解决的技术难题
b. 状态机的流转是另一大问题 ,在seata-java中的策略是路由
项目要求的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状态机流转的描述
-
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的开源实现 ,可以借鉴使用
测试是一个附加的功能点 ,seata-go-sample中需要提供关于saga事务模型的样例。测试案例可以参 考选取saga官网中使用的例子。相关状态机工具只需要继续沿用java实现即可。
测试关注几个要点:
- 能否解析成功state lang文件 ,并成功加载到状态机上?
- 状态机的流转能否遵从状态文件的约束?各状态的对应行为能否按要求执行?
实现测试需要完成的工作:
- 利用docker等工具实现微服务场景的模拟部署
- seata服务部署相关配置
- sample例子接入业务代码的实现
本人当前研一下 ,预期每周可以保证分出20小时投入到项目开发。对于开源世界本人向往已久 ,非 常希望借此机会做出一份贡献。对分布式相关技术既是本人当前兴趣所在 ,同时也是本人研究方向, 此前经历也和seata社区的目标非常吻合 ,也希望之后能参与更多seata社区建设。
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日)
◦ Saga
◦ Saga博客
• Saga理论相关 ◦ Chris
◦ paper
• 其他参考资料
◦ 原理解读