spring cloud微服务接入seata
- 一、环境简要说明
- 二、seata服务端部署
- 服务端下载
- 修改conf/registry.conf 配置
- 初始化seata在nacos中服务端配置
- 启动seata-server
- 三、初始化数据库
- 四、准备spring cloud微服务
- 五、测试验证
- 正常下单
- 异常下单
- 六、遇到的问题
- 无法获取seata-server服务注册的信息
- 获取nacos中的ip地址错误
一、环境简要说明
本文参照seata官方文档示例程序搭建,官网示例地址 环境准备
jdk 1.8版本,读者自行准备
mysql 8.0版本,读者自行准备,可参考笔者之前的安装教程
nacos 1.4.3版本,读者自行准备,可参考笔者之前的安装教程
二、seata服务端部署
服务端下载
下载seata1.4.2版本的服务端和源码
下载地址
修改conf/registry.conf 配置
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
dataId = "seataServer.properties"
}
}
初始化seata在nacos中服务端配置
参考文档在下载的源码路径seata-1.4.2\script\config-center\README.md
首先将源码目录下的seata-1.4.2\script\config-center\config.txt 和seata-1.4.2\script\config-center\nacos-config.sh 两个文件上传至192.168.220.125虚拟机中
nacos-config.sh文件赋执行权限
执行初始化命令
[root@host125 conf]# pwd
/opt/install/seata-server-1.4.2/conf
[root@host125 conf]# chmod +x nacos-config.sh
[root@host125 conf]# ./nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -u nacos -w nacos
set nacosAddr=localhost:8848
set group=SEATA_GROUP
cat: /opt/install/seata-server-1.4.2/config.txt: 没有那个文件或目录
=========================================================================
Complete initialization parameters, total-count:0 , failure-count:0
=========================================================================
Init nacos config finished, please start seata-server.
[root@host125 conf]# mv config.txt ..
[root@host125 conf]# ./nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -u nacos -w nacos
启动seata-server
[root@host125 bin]# pwd
/opt/install/seata-server-1.4.2/bin
[root@host125 bin]# sh seata-server.sh -p 8091 -h 192.168.220.125
三、初始化数据库
-- 创建 order库、业务表、undo_log表
create database seata_order;
use seata_order;
DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT 0,
`money` int(11) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;
-- 创建 stock库、业务表、undo_log表
create database seata_stock;
use seata_stock;
DROP TABLE IF EXISTS `stock_tbl`;
CREATE TABLE `stock_tbl` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`branch_id` BIGINT(20) NOT NULL,
`xid` VARCHAR(100) NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGBLOB NOT NULL,
`log_status` INT(11) NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
`ext` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8;
-- 初始化库存模拟数据
INSERT INTO seata_stock.stock_tbl (id, commodity_code, count) VALUES (1, 'product-1', 9999999);
INSERT INTO seata_stock.stock_tbl (id, commodity_code, count) VALUES (2, 'product-2', 0);
四、准备spring cloud微服务
微服务代码较多,读者可以下载源码自行参考,这里仅展示order服务的主要代码
bootstrap.yml
server:
port: 9091
spring:
application:
name: order-service
cloud:
nacos:
config:
server-addr: 192.168.220.125:8848
file-extension: yml
discovery:
# Nacos 注册中心地址
server-addr: 192.168.220.125:8848
# seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应
alibaba:
seata:
tx-service-group: my_test_tx_group
# 数据源配置
datasource:
url: jdbc:mysql://192.168.220.125:3306/seata_order?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
driverClassName: com.mysql.cj.jdbc.Driver
username: root
password: xxxxx
seata:
registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
# 参考tc服务自己的registry.conf中的配置
type: nacos
nacos: # tc
server-addr: 192.168.220.125:8848
namespace: ""
group: SEATA_GROUP
application: seata-server # tc服务在nacos中的服务名称
tx-service-group: my_test_tx_group # 事务组,根据这个获取tc服务的cluster名称
logging:
level:
io:
seata: debug
OrderController.java
package org.example.order.controller;
import org.example.order.feign.StockFeignClient;
import org.example.order.service.OrderService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("order")
public class OrderController {
@Resource
private OrderService orderService;
@Resource
private StockFeignClient stockFeignClient;
/**
* 下单:插入订单表、扣减库存,模拟回滚
*
* @return
*/
@RequestMapping("/placeOrder/commit")
public Boolean placeOrderCommit() {
orderService.placeOrder("1", "product-1", 1);
return true;
}
/**
* 下单:插入订单表、扣减库存,模拟回滚
*
* @return
*/
@RequestMapping("/placeOrder/rollback")
public Boolean placeOrderRollback() {
// product-2 扣库存时模拟了一个业务异常,
orderService.placeOrder("1", "product-2", 1);
return true;
}
@RequestMapping("/placeOrder")
public Boolean placeOrder(String userId, String commodityCode, Integer count) {
orderService.placeOrder(userId, commodityCode, count);
return true;
}
}
OrderServiceImpl.java
package org.example.order.service.impl;
import io.seata.spring.annotation.GlobalTransactional;
import org.example.order.dao.OrderDAO;
import org.example.order.feign.StockFeignClient;
import org.example.order.po.Order;
import org.example.order.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Service
public class OrderServiceImpl implements OrderService {
// @Resource
// private AccountFeignClient accountFeignClient;
@Resource
private StockFeignClient stockFeignClient;
@Resource
private OrderDAO orderDAO;
/**
* 下单:创建订单、减库存,涉及到两个服务
*
* @param userId
* @param commodityCode
* @param count
*/
@GlobalTransactional
@Transactional(rollbackFor = Exception.class)
public void placeOrder(String userId, String commodityCode, Integer count) {
BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
Order order = new Order();
order.setUserId(userId);
order.setCommodityCode(commodityCode);
order.setCount(count);
order.setMoney(orderMoney);
orderDAO.insert(order);
stockFeignClient.deduct(commodityCode, count);
}
// @Transactional(rollbackFor = Exception.class)
// public void create(String userId, String commodityCode, int count) {
//
// BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
//
// Order order = new Order();
// order.setUserId(userId);
// order.setCommodityCode(commodityCode);
// order.setCount(count);
// order.setMoney(orderMoney);
// orderDAO.insert(order);
//
// accountFeignClient.reduce(userId, orderMoney);
//
// }
}
五、测试验证
正常下单
http://localhost:9091/order/placeOrder/commit
异常下单
http://localhost:9091/order/placeOrder/rollback
stock服务报错
java.lang.RuntimeException: 异常:模拟业务异常:stock branch exception
at org.example.stock.service.impl.StockServiceImpl.deduct(StockServiceImpl.java:27) ~[classes/:na]
at org.example.stock.service.impl.StockServiceImpl$$FastClassBySpringCGLIB$$1e5615ce.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.example.stock.service.impl.StockServiceImpl$$EnhancerBySpringCGLIB$$e12feaf6.deduct(<generated>) ~[classes/:na]
at org.example.stock.controller.StockController.deduct(StockController.java:25) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118) ~[spring-web-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587) [tomcat-embed-core-9.0.22.jar:9.0.22]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.22.jar:9.0.22]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.22.jar:9.0.22]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
六、遇到的问题
无法获取seata-server服务注册的信息
ERROR 8136 — [imeoutChecker_1] i.s.c.r.netty.NettyClientChannelManager : no available server to connect.
原因分析:seata-all 0.7.1版本getNamingInstance().getAllInstances(PRO_SERVER_ADDR_KEY, clusters)无法指定group,导致使用默认的group获取nacos中实例,而我的seata-server服务是部署在SEATA-GROUP中的
解决:seata-all 1.3.0版本之后才支持nacos的group配置 ,因此版本必须大于1.3.0才可以 ,笔者升级版本到1.4.2后解决
[#2620] support group configuration in Nacos registry
获取nacos中的ip地址错误
ERROR 11048 — [ main] i.s.c.r.netty.NettyClientChannelManager : 0101 can not connect to 127.0.0.1:8091 cause:can not register RM,err:can not connect to services-server.
io.seata.common.exception.FrameworkException: can not register RM,err:can not connect to services-server.
at io.seata.core.rpc.netty.NettyClientChannelManager.doConnect(NettyClientChannelManager.java:225) ~[seata-all-1.4.2.jar:1.4.2]
at io.seata.core.rpc.netty.NettyClientChannelManager.acquireChannel(NettyClientChannelManager.java:107) ~[seata-all-1.4.2.jar:1.4.2]
at io.seata.core.rpc.netty.NettyClientChannelManager.reconnect(NettyClientChannelManager.java:189) ~[seata-all-1.4.2.jar:1.4.2]
at io.seata.core.rpc.netty.RmNettyRemotingClient.registerResource(RmNettyRemotingClient.java:194) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.AbstractResourceManager.registerResource(AbstractResourceManager.java:121) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.datasource.DataSourceManager.registerResource(DataSourceManager.java:90) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.DefaultResourceManager.registerResource(DefaultResourceManager.java:114) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.datasource.DataSourceProxy.init(DataSourceProxy.java:110) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.datasource.DataSourceProxy.(DataSourceProxy.java:96) [seata-all-1.4.2.jar:1.4.2]
at io.seata.rm.datasource.DataSourceProxy.(DataSourceProxy.java:81) [seata-all-1.4.2.jar:1.4.2]
at io.seata.spring.annotation.datasource.DataSourceProxyHolder.createDsProxyByMode(DataSourceProxyHolder.java:97) [seata-all-1.4.2.jar:1.4.2]
at io.seata.spring.annotation.datasource.DataSourceProxyHolder.putDataSource(DataSourceProxyHolder.java:88) [seata-all-1.4.2.jar:1.4.2]
我的seata-server是部署在虚拟机中的,不能通过127.0.0.1访问,如果是通过nacos获取的ip应该是192.168.220.125才对
原因分析:跟踪调试后发现seata-all 1.4.2版本registryTypeName获取的是file类型,并不是registry.conf文件中配置的nacos,具体原因未知,也懒得去分析了,直接配置文件中指定registry.type=nacos
解决:在微服务配置文件中指定registry.type=nacos
seata:
registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
# 参考tc服务自己的registry.conf中的配置
type: nacos
nacos: # tc
server-addr: 192.168.220.125:8848
namespace: ""
group: SEATA_GROUP
application: seata-server # tc服务在nacos中的服务名称
tx-service-group: my_test_tx_group # 事务组,根据这个获取tc服务的cluster名称