作者 | 刘晓敏 郝洪范
分布式事务简介
在这里简单介绍下分布式事务的原理:
- 事务的发起者(TM)要向事务协调器(TC)发起开启全局事务的请求
- 在业务执行完毕后,事务的发起者(TM)向事务协调器(TC)发起全局事务提交或者全局事务回滚
- 在全局事务开启后,事务的参与者(RM)要向事务协调器(TC)注册分支事务
- RM 本地业务执行完毕后,要向事务协调器(TC)报告分支事务的执行状态,即本地事务执行成功还是失败
- 事务协调器(TC)在收到全局提交或者全局回滚的请求后,会通知执行成功的事务参与者(RM)执行本地提交或者本地回滚
所以,TM 到 TC 都是发起单向的请求,RM 和 TC 之间的通信是双向的。
seata-golang 历史问题
从 2020 年 4 月 开始正式开源了 seata-golang 分布式事务框架,功能基本对齐 seata(java)。
需要着重强调的是:
- 为了双向通信,seata-golang 底层网络库使用的是 getty。(核心网络库:
http://seata.io/zh-cn/blog/seata-golang-communication-mode.html dubbogo ) - 在 TC 上保存了 client 的连接注册信息,在需要回调时,TC 才能准确地向对应的 client 发起回调请求。
- 为了 TC 的高可用,client 端需要保存每个 TC 的连接注册信息,以便在其中一个 TC 当机后选择另一个 TC 通信。
这个版本目前已经完全稳定,同时也在积极的改进中,支持了更多的特性,吸引了一些企业用户深度参与其中。
不过随着云原生时代的到来,kubernetes 被广泛的使用,seata-golang v1 版本的设计并不完全符合云原生的理念。
首先,client 需要知道每个 TC 的连接地址,并与每个 TC 保持连接,TC 也将每个 client 的连接信息保存在内部。在 kubernetes 环境下,每个容器重启后由于 ip 地址重新分配,client 要知道 TC 的 IP 地址必须依靠注册中心。
其次,RPC 协议采用了自己实现的编码协议,对协议栈的扩展不友好,对接入云原生产品增加了难度。
seata-golang grpc 版本
基于上述原因,我在今年 6 月使用 grpc 将 seata-golang 重构了一个版本。
(v2 版本:https://github.com/opentrx/seata-golang/tree/v2)
大概流程如下:
- client 端将 TC 的在 kubernetes 中的域名和端口配置到 serverAddressing,并将自己在 kubernetes 中的域名和端口配置到 addressing
- 在 client 端和 TC 用 grpc 进行通信的时候,使用 serverAddressing 去对 TC 进行服务发现
- TC 在回调 client 端时,通过 addressing 来对 client 进行服务发现。
client 端配置如下:
port: 8083 #分支事务暴露的端口,用于 TC 回调
addressing: aggregation.default.svc:8083 #client 端在 kubernetes 中的域名及端口
serverAddressing: seata.default.svc:8091 #TC 部署在 kubernetes 中的域名及端口
Transaction Mesh
Transaction Mesh 是一个美好的梦想,去年我在将 seata-golang 开源后就一直在思考怎么实现 transaction mesh。其实当时思路已经成型,但由于认识了解 seata-golang 的人比较少,我也担心我在闭门造车,就将这个想法搁置了。
今年 4 月、5 月,有幸得到 GOCN 社区和阿里的支持,在线下和许多开发者进行了面对面的交流,并且 seata-golang 也有了商业用户,通过交流认为 Transaction Mesh 还是有必要去实现的。
所以最近我又将 Seata-golang 的 TCC 模式集成到了 Mosn 中(pr 正在 review:
https://github.com/mosn/mosn/pull/1728 ),下面是 Mosn 集成 TCC 模式的原理图。
之所以选择 Mosn 而不是 Envoy 是因为自从毕业后就很少接触 C++,在 Envoy 上集成有些力不从心。而 Seata-golang 已经定义好和 TC 交互的 grpc 接口描述语言 seata.proto,要在 Envoy 上完成 Transaction Mesh 可以参考 Mosn 的实现,熟悉 C++ 对 Transaction Mesh 感兴趣的朋友,欢迎您来完成这个美好的梦想!
如果你有任何疑问,欢迎钉钉扫码加入交流群【钉钉群号 33069364】:
作者简介
刘晓敏 (GitHubID dk-lockdown),目前就职于 h3c 成都分公司,擅长使用 Go/Java 语言,在云原生和微服务相关技术方向均有涉猎,目前专攻分布式事务。
郝洪范 (GitHubID georgehao),dubbogo committer,目前就职于京东,擅长使用 Go/C++ 语言,目前在输出 Go 源码阅读与实战系列教程,擅长微服务相关事宜。
参考资料
- seata 官方:https://seata.io
- java 版 seata:https://github.com/seata/seata
- seata-golang 项目地址:https://github.com/opentrx/seata-golang
- driver 地址:https://github.com/opentrx/mysql
- seata-golang go 夜读 b站分享:https://www.bilibili.com/video/BV1oz411e72T
- 基于 getty 的 seata-golang 通信模型详解:
http://seata.io/zh-cn/blog/seata-golang-communication-mode.html
- seata-golang 接入指南:https://mp.weixin.qq.com/s/EYtPycuqIlKi5KJ_hzZPVA
- Go Mysql Driver 集成 Seata-Golang 解决分布式事务问题: