Seata 分布式事务配置实战:基于 Nacos 的高可用部署方案
1. 引言
在微服务架构中,分布式事务一直是绕不开的难题。Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的分布式事务解决方案,它提供了AT、TCC、SAGA、XA等多种事务模式,能够以零侵入的方式解决跨数据库、跨服务的分布式数据一致性问题。
本文将以Seata 1.5.2版本为例,手把手教你如何配置 Seata Server,并集成Nacos作为注册中心和配置中心,实现 Seata 的高可用部署。通过本文,你将掌握:
- ✅ Seata 的核心角色(TC、TM、RM)与工作流程
- ✅ 如何为 Seata Server 创建数据库表结构
- ✅ 如何配置 Nacos 作为 Seata 的注册中心和配置中心
- ✅ 如何启动并验证 Seata Server
2. Seata 核心架构概览
在开始配置之前,先了解一下 Seata 的三个核心组件:
- TC (Transaction Coordinator):Seata Server 独立部署,负责全局事务的协调与管理。
- TM (Transaction Manager):嵌入在业务应用中,负责开启全局事务、提交或回滚。
- RM (Resource Manager):嵌入在数据访问层,负责分支事务的注册、状态报告以及数据库操作。
Seata 通过 TC 来统一调度,TM 和 RM 通过注册中心(如 Nacos)感知 TC 的地址。
3. 环境准备
| 组件 | 版本 | 说明 |
|---|---|---|
| Seata Server | 1.5.2 | 事务协调器 |
| Nacos | 2.x | 注册中心 + 配置中心 |
| MySQL | 5.7 / 8.0 | Seata Server 存储事务日志 |
| Spring Cloud Alibaba | 2021.x 或更高 | 客户端集成参考 |
注意:本文配置基于 Seata 1.5.2,不同版本的配置文件路径和参数可能有所差异,请以实际下载版本为准。
4. 第一步:创建 Seata 数据库表
Seata Server 需要将全局事务会话、分支事务会话、锁等信息持久化到数据库中。官方提供了 MySQL 建表脚本。
4.1 下载脚本
访问 Seata 官方 GitHub 仓库(国内可使用 Gitee 镜像):
- GitHub 地址:
https://github.com/seata/seata/tree/v1.5.2/script/server/db - Gitee 地址(推荐):
https://gitee.com/seata-io/seata/tree/v1.5.2/script/server/db
需要下载以下 SQL 文件(以 MySQL 为例):
mysql.sql(包含global_table、branch_table、lock_table)mysql_distributed_lock.sql(包含distributed_lock)
4.2 执行建表
登录 MySQL,创建一个专门用于 Seata 的数据库(例如seata):
CREATEDATABASEIFNOTEXISTSseataDEFAULTCHARSETutf8mb4;USEseata;然后执行下载的 SQL 脚本。执行完成后,你会看到以下四张表:
| 表名 | 作用 |
|---|---|
global_table | 存储全局事务信息 |
branch_table | 存储分支事务信息 |
lock_table | 存储全局锁信息(AT 模式) |
distributed_lock | 分布式锁表(用于 Server 集群) |
5. 第二步:配置 Seata Server 的注册中心
Seata Server 启动后需要注册到 Nacos,以便客户端(TM/RM)能够发现它。
修改 Seata Server 配置文件:conf/application.yml(Seata 1.5+ 统一使用 YAML 配置)。
5.1 配置 registry(注册中心)
seata:registry:type:nacos# 注册中心类型nacos:application:seata-server# 服务名server-addr:127.0.0.1:8848# Nacos 地址group:SEATA_GROUP# 分组,需与客户端一致namespace:# 命名空间(可选,留空为 public)cluster:default# 集群名称username:# Nacos 用户名(如有)password:# Nacos 密码(如有)⚠️重要提示:客户端(微服务)中的注册中心配置必须与 Seata Server 配置在同一个 namespace 和 group,否则客户端将无法找到 Seata Server。
6. 第三步:配置 Seata Server 的配置中心
Seata Server 本身的配置(事务超时、存储模式、锁策略等)可以存放在 Nacos 中,实现动态刷新。这里我们将seataServer.properties文件的内容托管到 Nacos。
6.1 修改配置中心类型
在conf/application.yml中添加config部分:
seata:config:type:nacos# 配置中心类型nacos:server-addr:127.0.0.1:8848namespace:# 与 registry 保持一致group:SEATA_GROUPdata-id:seataServer.properties# 配置 dataIdusername:password:注意:
data-id是 Nacos 中配置文件的 dataId,后面需要在 Nacos 中创建同名的配置。
6.2 完整的 application.yml 示例
以下是整合了 server 端口、日志、安全、注册中心和配置中心的完整配置(基于你提供的原文整理):
server:port:7091# Seata Console 访问端口spring:application:name:seata-serverlogging:config:classpath:logback-spring.xmlfile:path:${user.home}/logs/seataconsole:user:username:seatapassword:seataseata:config:type:nacosnacos:server-addr:127.0.0.1:8848namespace:group:SEATA_GROUPdata-id:seataServer.propertiesusername:password:registry:type:nacosnacos:application:seata-serverserver-addr:127.0.0.1:8848group:SEATA_GROUPnamespace:cluster:defaultsecurity:secretKey:SeataSecretkey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds:1800000ignore:urls:-/**/*.css-/**/*.js-/**/*.html-/**/*.map-/**/*.svg-/**/*.png-/**/*.ico-/console-fe/public/**-/api/v1/auth/login注意:
security.secretKey用于生成 JWT token,生产环境请修改为自定义密钥。
7. 第四步:在 Nacos 中创建配置seataServer.properties
Seata Server 启动时会从 Nacos 读取data-id为seataServer.properties的配置。你需要将以下内容(根据你的环境微调)添加到 Nacos 配置中。
7.1 登录 Nacos 控制台
访问http://127.0.0.1:8848/nacos,在配置管理 → 配置列表中,选择命名空间public(或你指定的 namespace),点击新建配置。
- Data ID:
seataServer.properties - Group:
SEATA_GROUP - 配置格式:
Properties
7.2 配置内容(优化版)
以下配置包含了事务协调、存储模式(DB)、锁策略、客户端参数等核心项,并修正了原文中的拼写错误:
# 传输配置 transport.type=TCP transport.server=NIO transport.heartbeat=true transport.enableTcClientBatchSendRequest=false transport.enableRmClientBatchSendRequest=true transport.enableTcServerBatchSendResponse=false transport.rpcRmRequestTimeout=30000 transport.rpcTmRequestTimeout=30000 transport.rpcTcRequestTimeout=30000 transport.serialization=seata transport.compressor=none # 事务分组映射(重要:客户端使用时需要匹配) service.vgroupMapping.my_test_tx_group=default # 客户端 RM 配置 client.rm.asyncCommitBufferLimit=10000 client.rm.lock.retryInterval=10 client.rm.lock.retryTimes=30 client.rm.lock.retryPolicyBranchRollbackOnConflict=true client.rm.reportRetryCount=5 client.rm.tableMetaCheckEnable=true client.rm.tableMetaCheckerInterval=60000 client.rm.sqlParserType=druid client.rm.reportSuccessEnable=false # 客户端 TM 配置 client.tm.commitRetryCount=5 client.tm.rollbackRetryCount=5 client.tm.defaultGlobalTransactionTimeout=60000 client.tm.degradeCheck=false client.tm.degradeCheckAllowTimes=10 client.tm.degradeCheckPeriod=2000 # 撤销日志配置 client.undo.dataValidation=true client.undo.logSerialization=jackson client.undo.onlyCareUpdateColumns=true client.undo.logTable=undo_log client.undo.compress.enable=true client.undo.compress.type=zip client.undo.compress.threshold=64k # 存储模式(DB 模式) store.mode=db store.lock.mode=db store.session.mode=db # 数据库连接池配置 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver store.db.url=jdbc:mysql://localhost:3306/seata?useUnicode=true&rewriteBatchedStatements=true&useLocalSessionState=true store.db.user=root store.db.password=root store.db.minConn=5 store.db.maxConn=30 store.db.globalTable=global_table store.db.branchTable=branch_table store.db.distributedLockTable=distributed_lock store.db.queryLimit=100 store.db.lockTable=lock_table store.db.maxWait=5000 # 服务器恢复策略 server.recovery.committingRetryPeriod=1000 server.recovery.asynCommittingRetryPeriod=1000 server.recovery.rollbackingRetryPeriod=1000 server.recovery.timeoutRetryPeriod=1000 server.maxCommitRetryTimeout=-1 server.maxRollbackRetryTimeout=-1 server.rollbackRetryTimeoutUnlockEnable=false server.distributedLockExpireTime=10000 # 会话管理 server.session.branchAsyncQueueSize=5000 server.session.enableBranchAsyncRemove=false # 指标监控 metrics.enabled=false metrics.registryType=compact metrics.exporterList=prometheus metrics.exporterPrometheusPort=9898📌关键修改说明:
- 修正了
service.vgroupMapping.mal1_order_tx_group为示例名称my_test_tx_group,你可按需修改。- 修正了
store.db.url中的拼写错误(useuni code→useUnicode)。- 补充了缺失的
store.db.distributedLockTable配置(对应第四张表)。
8. 第五步:启动 Seata Server
8.1 启动命令
进入 Seata Server 的bin目录,执行启动脚本:
- Linux/Mac:
./seata-server.sh - Windows:
seata-server.bat
启动成功后,你会看到日志中出现:
Server started, listen port: 8091 Console started, listen port: 7091- 8091:TC 服务端口,用于与客户端(TM/RM)通信,并注册到 Nacos
- 7091:Seata Console(可视化控制台)访问端口,提供 Web UI
8.2 访问控制台
打开浏览器访问:http://localhost:7091
默认登录账号:seata/seata
登录后,你可以查看全局事务、事务统计等信息。
8.3 在 Nacos 中验证注册
登录 Nacos 控制台,进入服务管理 → 服务列表,选择命名空间(与配置一致),应能看到seata-server服务以及一个健康的实例。
9. 整体流程回顾
10. 常见问题与排障
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
Seata Server 启动报错Failed to connect to Nacos | Nacos 地址或端口错误 | 检查application.yml中server-addr是否正确,Nacos 是否已启动 |
| 服务注册成功,但客户端无法获取 TC 地址 | 客户端与 Server 的 namespace/group 不一致 | 确保客户端配置中的registry.nacos.group和namespace与 Server 完全相同 |
data-id未找到配置 | Nacos 中未创建seataServer.properties或 group/dataId 不匹配 | 检查 Nacos 配置列表,确认 dataId 和 group 与application.yml一致 |
客户端事务执行失败,日志显示no available service | 事务分组映射错误 | 检查客户端seata.tx-service-group与 Server 端service.vgroupMapping.xxx是否对应 |
| 数据库连接失败 | store.db.url配置错误或数据库未启动 | 确认 MySQL 可访问,且用户名密码正确 |
11. 总结
本文详细介绍了 Seata 1.5.2 基于 Nacos 的配置全过程,包括:
- ✅ 数据库表结构初始化
- ✅ Seata Server 注册中心(Nacos)配置
- ✅ Seata Server 配置中心(Nacos)配置
- ✅ 将核心参数存储在 Nacos 中,实现动态刷新
- ✅ 启动验证与控制台使用
通过这套配置,Seata Server 可以集群化部署,多实例通过 Nacos 实现服务发现,达到高可用效果。后续的文章中,我们将进一步介绍如何在 Spring Cloud 微服务中集成 Seata 客户端,并实战演示 AT 模式的分布式事务。
下个问题:Spring Cloud Alibaba + Seata 分布式事务实战(AT模式)