当前位置: 首页 > 科技观察

那些用Go实现的分布式事务框架

时间:2023-03-20 16:35:50 科技观察

本文转载自微信公众号《RememberGo》,作者吴钦库里。转载请联系RememberGo公众号。不知不觉,开篇文章已经一个月没有更新了。人一旦懒惰,只会越来越懒。最近对分布式事务产生了兴趣,查阅了一些文章和论文。本文主要介绍我看到的两个项目,不涉及一些理论知识。阿里开源版的Seata主要是看Go实现的seata-golang(java版后面)和前段时间很多公众号发布的dtm。Seata简介Seata是阿里巴巴开源的分布式事务服务。目前为用户提供AT、TCC、SAGA、XA事务模式,整体采用两阶段提交协议。seata-golang的Go版本目前好像只实现了mysql的AT和TCC模式,作者暂不更新。Seata有几个核心角色:TC(TransactionCoordinator)——交易协调员。(维护全局和分支事务的状态,驱动全局事务提交或回滚)TM(TransactionManager)——事务管理器。(定义全局事务的范围:启动全局事务,提交或回滚全局事务。)RM(资源管理器)-资源管理器。(管理分支事务处理的资源,与TC对话注册分支事务并上报分支事务状态,驱动分支事务提交或回滚)当然这样看,我可能不是很理解。我在官网上用图来说明。从上图可以看出,三个角色分别负责以下任务。TC维护全局和分支的事务状态,需要存储。当一个分布式事务结束时,需要通知每个RM是commit还是rollback。TM请求TC启动分布式事务,获得一个全局唯一的分布式id。根据第一阶段参与分布式事务的各个RM的反馈,决定在第二阶段请求TC提交或回滚分布式事务(在大多数场景下,如果任何一个RM在第一阶段失败,这分布式事务失败)说白了,RM就是管理参与分布式事务的各种服务(比如经典下单场景中涉及的:订单服务、库存服务、营销服务等)ps:这里的RM个人感觉有点类似于微服务处理层的中间层(在技术术语中,他们称此为bff->backendforfronted)。单阶段准备行为(主动):每个RM调用自定义准备逻辑。两阶段提交行为(被动触发):如果本次分布式事务的第一阶段所有RM都成功,TC处理完自己的状态变化后,会调用各个RM自定义的提交逻辑。(第一阶段所有RM成功)第二阶段回滚行为(被动触发):如果任何一个RM在分布式事务第一阶段失败,TC会在处理完自己的状态变化后调用每个RM自定义的回滚逻辑.(任何RM在第一阶段都失败了)好的。下面我们来看一下seata-golang的一些实现细节。seata-golang底层使用gRPC进行通信。在seata-golang中,我们先来看一下RM的部分结构。对于manager,保存支持的主要事务模式实现(TCC、XA等),每个模式只需要实现这个接口即可。再次查看TC部分结构(删除一些字段)。TC目前支持mysql和pgsql进行数据存储,即只要实现SessionManager接口,然后注入SessionHolder的manager即可。介绍完这两个基本结构,大家还记得我们上面提到的它们之间的关系吗?第二阶段,TC会根据当前事务状态通知RM是commit还是rollback。在初始化ResourceManager的时候,我们看到最终会调用TC的一个grpc接口branchCommunicate。对应服务器。我们知道gRPC有四种基本的通信模式。一元RPC(UnaryRPC)服务器流式RPC(ServerStreamingRPC)客户端流式RPC(ClientStreamingRPC)双向流式RPC(BidirectionalStreamingRPC)想要流的形式也很简单,只需要在proto方法在request|response参数前加上stream标签,则此接口为stream。至于是什么流,就看你在什么地方添加流了。如果request和response都加了,那么就是双向流。client和server都可以通过stream发送请求。通过stream.Recv发送和接收数据。当RM调用BranchCommunicate时,最终处理分支事务调用manager.BranchCommit。相应的,当TC被RM调用BranchCommunicate时,它是如何将commit或rollback数据发送给RM的呢?当TC要通知RM到branchcommit时,最后一个就是TM,这个也不难理解。其实seat-golang还有一点要说的。比如通过go反射实现的动态代理功能(虽然我觉得完全没有必要?),懒得写了。这篇文章再写就长了,我就不继续写dtm了,有兴趣的可以留言,我看看要不要写个dtm。参考https://seata.io/zh-cn/docs/overview/what-is-seata.htmlhttps://github.com/opentrx/seata-golang