从单体到微服务:用Docker Compose一键部署Seata Server + Nacos,搭建你的分布式事务实验场
从单体到微服务用Docker Compose一键部署Seata Server Nacos搭建你的分布式事务实验场在微服务架构的演进过程中分布式事务一直是开发者面临的核心挑战之一。Apache Seata作为一款开源的分布式事务解决方案通过与Nacos服务发现和配置中心的深度集成为微服务架构提供了可靠的事务协调能力。本文将带你从零开始使用Docker Compose快速搭建一个包含Seata Server和Nacos的完整实验环境让你能够在本地轻松模拟和测试分布式事务的各种场景。1. 环境准备与架构设计在开始部署之前我们需要先了解整个技术栈的架构设计。Seata Server作为事务协调器需要与Nacos服务发现中心进行交互同时还需要一个数据库来存储事务日志。我们将使用Docker Compose来编排这三个组件确保它们能够协同工作。1.1 所需组件及版本Seata Server: 1.6.1Nacos Server: 2.2.1MySQL: 8.0Docker Compose: v21.2 网络架构设计为了确保容器间能够正常通信我们需要创建一个自定义的Docker网络。这样Seata Server和Nacos就可以通过服务名互相访问而不需要关心IP地址的变化。docker network create seata-network2. Docker Compose编排配置我们将使用一个docker-compose.yml文件来定义所有服务。这个文件包含了Seata Server、Nacos和MySQL的配置以及它们之间的依赖关系。2.1 完整的docker-compose.ymlversion: 3.8 services: nacos: image: nacos/nacos-server:2.2.1 container_name: nacos ports: - 8848:8848 - 9848:9848 environment: - MODEstandalone - SPRING_DATASOURCE_PLATFORMmysql - MYSQL_SERVICE_HOSTmysql - MYSQL_SERVICE_DB_NAMEnacos_config - MYSQL_SERVICE_USERroot - MYSQL_SERVICE_PASSWORDroot volumes: - ./nacos/logs:/home/nacos/logs networks: - seata-network depends_on: - mysql mysql: image: mysql:8.0 container_name: mysql ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORDroot - MYSQL_DATABASEnacos_config volumes: - ./mysql/data:/var/lib/mysql - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql networks: - seata-network seata: image: seataio/seata-server:1.6.1 container_name: seata ports: - 7091:7091 - 8091:8091 environment: - SEATA_IPseata - STORE_MODEdb volumes: - ./seata/resources:/seata-server/resources networks: - seata-network depends_on: - nacos - mysql networks: seata-network: external: true2.2 关键配置解析Nacos配置使用standalone模式运行配置MySQL作为持久化存储暴露8848(HTTP)和9848(GRPC)端口MySQL配置初始化nacos_config数据库挂载数据卷保证数据持久化Seata配置配置DB模式存储事务日志挂载自定义配置文件目录依赖Nacos和MySQL服务3. 数据库初始化与配置在启动服务之前我们需要初始化数据库结构。这包括为Nacos和Seata创建所需的数据库表。3.1 Nacos数据库初始化创建mysql/init.sql文件内容如下CREATE DATABASE IF NOT EXISTS nacos_config CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE IF NOT EXISTS seata CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE nacos_config; -- Nacos所需的表结构 -- 这里应该包含Nacos官方提供的SQL脚本内容3.2 Seata数据库初始化继续在init.sql文件中添加Seata所需的表结构USE seata; -- 全局事务表 CREATE TABLE IF NOT EXISTS global_table ( xid VARCHAR(128) NOT NULL, transaction_id BIGINT, status TINYINT NOT NULL, application_id VARCHAR(32), transaction_service_group VARCHAR(32), transaction_name VARCHAR(128), timeout INT, begin_time BIGINT, application_data VARCHAR(2000), gmt_create DATETIME, gmt_modified DATETIME, PRIMARY KEY (xid), KEY idx_gmt_modified_status (gmt_modified, status), KEY idx_transaction_id (transaction_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 分支事务表 CREATE TABLE IF NOT EXISTS branch_table ( branch_id BIGINT NOT NULL, xid VARCHAR(128) NOT NULL, transaction_id BIGINT, resource_group_id VARCHAR(32), resource_id VARCHAR(256), branch_type VARCHAR(8), status TINYINT, client_id VARCHAR(64), application_data VARCHAR(2000), gmt_create DATETIME, gmt_modified DATETIME, PRIMARY KEY (branch_id), KEY idx_xid (xid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 全局锁表 CREATE TABLE IF NOT EXISTS lock_table ( row_key VARCHAR(128) NOT NULL, xid VARCHAR(96), transaction_id BIGINT, branch_id BIGINT NOT NULL, resource_id VARCHAR(256), table_name VARCHAR(32), pk VARCHAR(36), gmt_create DATETIME, gmt_modified DATETIME, PRIMARY KEY (row_key), KEY idx_branch_id (branch_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;4. Seata Server详细配置Seata的配置主要包含两个部分application.yml和Nacos中的配置项。我们将通过挂载卷的方式来自定义这些配置。4.1 application.yml配置在seata/resources目录下创建application.yml文件server: port: 7091 spring: application: name: seata-server seata: config: type: nacos nacos: server-addr: nacos:8848 namespace: group: SEATA_GROUP username: nacos password: nacos ># 事务日志存储模式 store.modedb # 数据库配置 store.db.datasourcedruid store.db.db-typemysql store.db.driver-class-namecom.mysql.cj.jdbc.Driver store.db.urljdbc:mysql://mysql:3306/seata?useSSLfalsecharacterEncodingutf8 store.db.userroot store.db.passwordroot store.db.min-conn5 store.db.max-conn30 # 事务组映射 service.vgroupMapping.default_tx_groupdefault # 仅允许内网访问 transport.enable-client-batch-send-requestfalse transport.thread-factory.boss-thread-prefixNettyBoss transport.thread-factory.worker-thread-prefixNettyServerNIOWorker transport.thread-factory.server-executor-thread-prefixNettyServerBizHandler transport.thread-factory.share-boss-workerfalse transport.thread-factory.client-selector-thread-prefixNettyClientSelector transport.thread-factory.client-selector-thread-size1 transport.thread-factory.client-worker-thread-prefixNettyClientWorkerThread transport.thread-factory.boss-thread-size1 transport.thread-factory.worker-thread-sizedefault transport.shutdown.wait35. 启动与验证完成所有配置后我们可以启动整个环境并进行验证。5.1 启动服务docker-compose up -d这个命令会按照依赖顺序启动所有服务首先启动MySQL并初始化数据库然后启动Nacos并连接到MySQL最后启动Seata并连接到Nacos和MySQL5.2 服务验证验证Nacos 访问http://localhost:8848/nacos使用默认账号(nacos/nacos)登录应该能看到seata-server已经注册。验证Seata 访问http://localhost:7091应该能看到Seata的管理控制台。验证数据库 连接到MySQL检查seata数据库中的表是否已创建。5.3 常见问题排查服务无法互相发现 检查容器是否在同一个网络(seata-network)中使用docker network inspect seata-network查看。Nacos无法连接MySQL 检查MySQL容器的日志确认初始化SQL是否执行成功。Seata无法启动 检查挂载的配置文件是否正确特别是数据库连接信息。6. 实验环境使用指南现在你已经拥有了一个完整的分布式事务实验环境。下面是一些你可以尝试的实验场景6.1 模拟分布式事务创建两个简单的微服务分别操作不同的数据库使用GlobalTransactional注解标记分布式事务方法观察Seata如何协调这两个服务的事务6.2 测试事务回滚在第一个服务成功执行后在第二个服务中故意抛出异常观察第一个服务的操作是否被正确回滚6.3 性能测试模拟高并发场景下的分布式事务监控Seata Server的资源使用情况调整连接池参数观察性能变化7. 进阶配置与优化对于生产环境或更复杂的测试场景你可能需要进行以下优化7.1 Seata Server高可用部署多个Seata Server实例使用Nacos集群模式配置Seata的集群支持7.2 性能调优# 在seataServer.properties中添加以下配置 server.recovery.committing-retry-period1000 server.recovery.asyn-committing-retry-period1000 server.recovery.rollbacking-retry-period1000 server.recovery.timeout-retry-period1000 server.max.commit.retry.timeout-1 server.max.rollback.retry.timeout-1 server.rollback.retry.timeout.unlock-enablefalse server.distributed.lock.expire.time100007.3 监控与告警集成Prometheus监控Seata指标配置Grafana仪表盘设置关键指标的告警规则在实际项目中我们发现合理配置连接池参数和重试策略可以显著提高分布式事务的成功率。特别是在网络不稳定的环境下适当增加重试次数和超时时间能够有效减少事务失败的情况。