自从 seata-golang 开源以来,社区的同学都比较关心它的性能。2020 年 12 月 12 日,我利用周末的时间用 jmeter 对它进行了测试。
测试的 demo 为项目 samples/at 中的 demo,数据库为本地 docker 中搭建的 mysql,测试工具为 jmeter。电脑配置如下:
jmeter 参数如下:
100 个线程循环 10 次访问 http://localhost:8003/createSoCommit。
该接口调用一个聚合服务创建订单,聚合服务分别调用订单服务写入订单,再调用库存服务分配库存。
1、配置 demo 中的 tc server 为 seata-golang 项目中的 tc server,测试结果如下:
go client 连接 go tc server:
Label | # 样本 | 平均值 | 中位数 | 90% 百分位 | 95% 百分位 | 99% 百分位 | 最小值 | 最大值 | 异常 % | 吞吐量 | 接收 KB/sec | 发送 KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|---|
HTTP请求 | 400 | 3978 | 4290 | 4566 | 4603 | 4883 | 420 | 5105 | 0.00% | 22.34512 | 3.47 | 3.58 |
总体 | 400 | 3978 | 4290 | 4566 | 4603 | 4883 | 420 | 5105 | 0.00% | 22.34512 | 3.47 | 3.58 |
2、配置 demo 中的 tc server 为 java 版 seata 的 tc server,测试结果如下:
go client 连接 java tc server (version 1.4):
Label | # 样本 | 平均值 | 中位数 | 90% 百分位 | 95% 百分位 | 99% 百分位 | 最小值 | 最大值 | 异常 % | 吞吐量 | 接收 KB/sec | 发送 KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|---|
HTTP请求 | 400 | 4222 | 4340 | 5206 | 5490 | 5841 | 244 | 6129 | 0.00% | 20.62175 | 3.2 | 3.3 |
总体 | 400 | 4222 | 4340 | 5206 | 5490 | 5841 | 244 | 6129 | 0.00% | 20.62175 | 3.2 | 3.3 |
3、另一个 java seata 的 demo 与 seata-golang 中的 demo 做了相同的操作,即通过一个聚合服务调用订单服务、再调用库存服务创建订单,通过 jmeter 对创建订单接口进行测试,测试结果如下:
java client 连接 java tc server (version 1.4,client 设置 LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT 为 false ):
Label | # 样本 | 平均值 | 中位数 | 90% 百分位 | 95% 百分位 | 99% 百分位 | 最小值 | 最大值 | 异常 % | 吞吐量 | 接收 KB/sec | 发送 KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|---|
HTTP请求 | 400 | 5357 | 5152 | 6401 | 7639 | 8980 | 2805 | 9301 | 0.00% | 16.8691 | 3.48 | 2.93 |
总体 | 400 | 5357 | 5152 | 6401 | 7639 | 8980 | 2805 | 9301 | 0.00% | 16.8691 | 3.48 | 2.93 |
4、java demo 连接 go tc server,该用例存在一些问题,下面的数据仅供参考,不参与此次对比:
Label | # 样本 | 平均值 | 中位数 | 90% 百分位 | 95% 百分位 | 99% 百分位 | 最小值 | 最大值 | 异常 % | 吞吐量 | 接收 KB/sec | 发送 KB/sec |
---|---|---|---|---|---|---|---|---|---|---|---|---|
HTTP请求 | 1000 | 7990 | 2660 | 30033 | 31832 | 70188 | 96 | 115046 | 0.00% | 8.55293 | 3.5 | 1.49 |
总体 | 1000 | 7990 | 2660 | 30033 | 31832 | 70188 | 96 | 115046 | 0.00% | 8.55293 | 3.5 | 1.49 |
问题:seata-golang 和 java 连接机制不同:seata-golang client 端的 tm 和 rm 是共用的和 tc server 的连接(默认一个应用和 tc server 保持一条连接),在一个连接上既传递 tm 消息也传递 rm 消息;
java 版 seata 设计的 tm 会和 tc server 建立一条连接,rm 也会和 tc server 建立一条连接,(默认一个应用和 tc server 保持两条连接)这导致了 ChannelManager 管理上的复杂,并且代码也比较难以理解,代码参见 ChannelManager.go。
此时创建了订单,在异步提交的时候,go tc server range 随机选择一条 java client 连接发送 BranchCommitRequest 消息,如果选中了 tm 创建的连接,会导致这个消息得不到处理。
综合上面的测试结果,go 和 java 性能差不多,在 java client LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT 设置为 false 的情况下,go 性能更好。