Ubuntu 22.04 安装 Apache Seata 2.6 指南

从零在 Ubuntu 22.04 安装 Apache Seata 2.6.0 事务协调器(TC):JDK 准备、官方包下载校验、file/db 两种存储模式配置启动、systemd 托管与 AT 模式回滚实测

Apache SeataSeata分布式事务Java2026/10/15

Ubuntu 22.04 安装 Apache Seata 2.6 指南

目标:在 Ubuntu 22.04 服务器上从零安装并运行 Apache Seata 2.6.0 事务协调器(seata-server),覆盖 JDK 准备、官方二进制下载与 sha512 校验、file/db 两种存储模式的完整配置与启动、systemd 托管、JVM 内存调整,并用一个真实的 AT 模式全局事务回滚实验验证安装结果。全文命令与输出均实测于 Ubuntu 22.04 + OpenJDK 17。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64)
  • Java:OpenJDK 17(apt 源 openjdk-17-jre-headless)
  • Seata 版本:2.6.0(孵化器发行包 apache-seata-2.6.0-incubating-bin.tar.gz,183MB)
  • 安装目录:/opt/seata/seata-server(TC)、/opt/seata/seata-namingserver(命名服务/控制台,2.6.0 需 JDK 25+,见第十一章)
  • 配置文件:/opt/seata/seata-server/conf/application.yml
  • 端口:8091(TC 服务)、8081(namingserver 控制台)
  • 数据库(db 存储模式用):MySQL 8,地址 seata-db:3306,库名 seata,账号 root/q1w2e3r4

二、前置条件

2.1 安装 JDK 与基础工具

seata-server 2.6.0 本体可在 JDK 8~17 上运行,本文使用 JDK 17:

apt-get update
apt-get install -y openjdk-17-jre-headless wget curl

实测安装完成后验证版本:

java -version
openjdk version "17.0.13" 2024-10-15
OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu122.04)
OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu122.04, mixed mode, sharing)

⚠️ 注意:openjdk-17-jre-headless 不含 jps 工具;如需用 jps 查看 JVM 参数,改装 openjdk-17-jdk-headless,或用本文第 5.3 节的 ps -ef 方式验证。

2.2 db 存储模式的前置数据库(可跳过)

file 模式无需数据库,可直接跳到第三章。若准备用 db 模式(集群必需),先准备一个 MySQL 8 实例并创建 seata 库:

mysql -h seata-db -uroot -pq1w2e3r4 -e "CREATE DATABASE IF NOT EXISTS seata DEFAULT CHARACTER SET utf8mb4;"

三、版本选型说明

Seata 处于 Apache 孵化器阶段,版本发布较快。本文撰写时(2026-10)各渠道版本情况:

渠道可得版本说明
Apache 官方 CDN(dlcdn)2.6.0当前最新 GA,推荐
Apache 归档(archive.apache.org/dist/incubator/seata/)2.5.0 及更早旧版本归档,仅存量兼容用
GitHub Releases(apache/incubator-seata)全版本同一二进制包的镜像渠道

查询最新版本的命令:

curl -s https://dlcdn.apache.org/incubator/seata/ | grep -oE 'href="[0-9.]+/"' | sort -V

本文选择 2.6.0:包含 2.x 的统一控制台(namingserver 承载)、raft 存储模式等能力,且是 CDN 当前主推版本。

四、官方包下载与校验

下载官方二进制包与 sha512 校验文件并校验完整性:

cd /tmp
wget https://dlcdn.apache.org/incubator/seata/2.6.0/apache-seata-2.6.0-incubating-bin.tar.gz
wget https://dlcdn.apache.org/incubator/seata/2.6.0/apache-seata-2.6.0-incubating-bin.tar.gz.sha512
sha512sum -c apache-seata-2.6.0-incubating-bin.tar.gz.sha512

实测输出:

apache-seata-2.6.0-incubating-bin.tar.gz: OK
ls -lh apache-seata-2.6.0-incubating-bin.tar.gz
-rw-r--r-- 1 root root 183M Oct 15 01:12 apache-seata-2.6.0-incubating-bin.tar.gz

💡 说明:如服务器下载 Apache 官方 CDN 较慢,可改用 GitHub Release 镜像渠道 https://github.com/apache/incubator-seata/releases/download/v2.6.0/apache-seata-2.6.0-incubating-bin.tar.gz,两个渠道包内容一致,务必配合 sha512 校验。

五、解压安装与目录结构

5.1 解压到 /opt/seata

mkdir -p /opt/seata
tar -xzf /tmp/apache-seata-2.6.0-incubating-bin.tar.gz -C /opt/seata --strip-components=1
ls /opt/seata
DISCLAIMER  seata-namingserver  seata-server

2.6.0 发行包包含两个部署单元:seata-server/(TC 本体)与 seata-namingserver/(命名服务+控制台)。本文第五~十章只运行 TC 本体。

5.2 关键目录结构

ls /opt/seata/seata-server
bin  conf  DISCLAIMER  Dockerfile  ext  lib  NOTICE  script  target
路径用途
bin/seata-server.sh启动/停止脚本(支持 -p -h -m -n -e 等参数)
conf/application.yml主配置文件(注册中心/配置中心/存储/事务组)
conf/application.example.yml全量参数示例(含各注册中心与存储模板)
lib/jdbc/db 模式 JDBC 驱动目录(官方包不内置驱动,需手动放置)
script/server/db/TC 存储建表脚本(mysql/postgresql/oracle/sqlserver/dm/kingbase/oscar)
script/client/at/db/客户端 AT 模式 undo_log 建表脚本
target/seata-server.jar启动入口 jar(loader.path 加载 lib)

六、file 存储模式快速启动(验证安装)

6.1 修改 JVM 堆内存(重要)

启动脚本默认堆为 2GB(JVM_XMS/JVM_XMX 默认 2048m)。测试环境或小内存服务器建议调整为 512MB。编辑 bin/seata-setup.sh(JVM 参数集中在此脚本),或直接以环境变量覆盖,本例用环境变量方式:

export JVM_XMS=512m JVM_XMX=512m

💡 说明:seata-setup.sh 的 JVM 参数优先级为"显式环境变量 > 自动按运行环境内存计算 > 默认 2048m"。实测在 1GB 内存环境中未显式指定时,脚本会打印 Auto set JVM heap to 716m (total memory: 1024MB, heap%: 70%)。生产 4GB+ 内存机器建议 1~2GB 堆。

6.2 启动并确认

cd /opt/seata/seata-server
bash bin/seata-server.sh -p 8091 > /tmp/seata-start.log 2>&1 &
sleep 15
grep -E 'Server started|started in' /root/logs/seata/seata-server.8091.all.log

实测输出:

[main] [rpc.netty.NettyServerBootstrap] [start] : Server started, service listen port: 8091
[main] [ache.seata.server.ServerRunner] [run] : seata server started in 321 millSeconds

⚠️ 注意:启动脚本必须用 bash 执行,sh bin/seata-server.sh(dash 解释器)会报 bin/seata-server.sh: 34: Bad substitution。

6.3 验证 JVM 生效堆

ps -ef | grep '[j]ava' | head -1

实测输出(节选):

/usr/bin/java  -Dlog.home=/root/logs/seata -server -Dloader.path=/opt/seata/seata-server/lib -Xmx512m -Xms512m -Xss640k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m ... -jar /opt/seata/seata-server/target/seata-server.jar -p 8091 &

-Xmx512m -Xms512m 即环境变量覆盖生效的证据。

6.4 停止

bash bin/seata-server.sh stop

七、systemd 托管(推荐生产使用)

生产环境建议用 systemd 托管 seata-server。⚠️ 以下操作需要一台具备 systemd 的 Linux 真机(或等效虚拟机),本文按真实服务器完整给出。

创建 /etc/systemd/system/seata-server.service:

[Unit]
Description=Apache Seata Server (TC)
After=network.target

[Service]
Type=forking
User=root
WorkingDirectory=/opt/seata/seata-server
Environment=JVM_XMS=512m
Environment=JVM_XMX=512m
ExecStart=/bin/bash /opt/seata/seata-server/bin/seata-server.sh -p 8091
ExecStop=/bin/bash /opt/seata/seata-server/bin/seata-server.sh stop
Restart=on-failure
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

⚠️ 注意:seata-server.sh 内部以 nohup ... & 后台拉起 JVM,systemd 需用 Type=forking;每行 Environment= 仅能设置一个变量,逐行书写。

启用并启动:

systemctl daemon-reload
systemctl enable seata-server
systemctl start seata-server
systemctl is-active seata-server

预期输出:

active

八、db 存储模式配置(集群前置)

8.1 导入建表脚本

mysql -h seata-db -uroot -pq1w2e3r4 -D seata < /opt/seata/seata-server/script/server/db/mysql.sql
mysql -h seata-db -uroot -pq1w2e3r4 -e "SHOW TABLES FROM seata;"

实测输出:

branch_table
distributed_lock
global_table
lock_table
vgroup_table

💡 技术拓展:五张表的作用——global_table 存全局事务(XID、状态、发起应用);branch_table 存分支事务;lock_table 存全局锁(行锁键),是 AT 模式写隔离的核心;distributed_lock 用于集群多 TC 间互斥任务(如异步过期清理);vgroup_table 存事务组到集群的路由映射。

8.2 放置 MySQL JDBC 驱动(必做)

官方发行包不带任何 JDBC 驱动,直接切 db 模式启动会失败(真实报错见第十二章 Q3)。手动下载驱动放入 lib/jdbc/:

mkdir -p /opt/seata/seata-server/lib/jdbc
wget -O /opt/seata/seata-server/lib/jdbc/mysql-connector-j-8.4.0.jar \
  https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.4.0/mysql-connector-j-8.4.0.jar
ls -lh /opt/seata/seata-server/lib/jdbc/

实测输出:

-rw-r--r-- 1 root root 2.5M Oct 15 01:38 mysql-connector-j-8.4.0.jar

8.3 修改 application.yml 切换 db 模式

在 conf/application.yml 中把 seata.store.mode 改为 db,并追加 store.db 连接段(完整文件示例见《Apache Seata 2.6 配置参数详解》第八节生产模板):

seata:
  store:
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://seata-db:3306/seata?rewriteBatchedStatements=true&useSSL=false&serverTimezone=Asia/Shanghai
      user: root
      password: q1w2e3r4
      min-conn: 5
      max-conn: 30
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      vgroup-table: vgroup_table
      query-limit: 1000
      max-wait: 5000

💡 说明:url 中主机名 seata-db 为数据库服务器地址,按实际环境修改;distributed-lock-table 与 vgroup-table 在 mysql.sql 2.6.0 版中随主脚本一并创建。

8.4 重启并确认 db 模式生效

bash bin/seata-server.sh stop
JVM_XMS=512m JVM_XMX=512m bash bin/seata-server.sh -p 8091 > /tmp/seata-start-db.log 2>&1 &
sleep 20
grep -E 'Server started|started in' /root/logs/seata/seata-server.8091.all.log | tail -2

实测输出:

Server started, service listen port: 8091
seata server started in 278 millSeconds

启动后可通过控制台或 SQL 验证会话写入(发起一笔事务后):SELECT xid,status FROM seata.global_table;(事务结束后记录被异步清理,查询到空为正常)。

九、开放端口与防火墙

若服务器启用 ufw,放行 TC 服务端口与控制台端口:

ufw allow 8091/tcp
ufw allow 8081/tcp

十、安装结果验证:AT 模式全局事务回滚实测

本节用一个最小 Spring Boot 客户端发起一笔"两步 UPDATE、第二步失败"的全局事务,验证 TC 工作正常且回滚生效。客户端依赖 org.apache.seata:seata-spring-boot-starter:2.6.0(Maven),业务库需先建 undo_log 表:

CREATE TABLE undo_log (
  branch_id BIGINT NOT NULL COMMENT 'branch transaction id',
  xid VARCHAR(128) NOT NULL COMMENT 'global transaction id',
  context VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
  rollback_info LONGBLOB NOT NULL COMMENT 'rollback info',
  log_status INT NOT NULL COMMENT '0:normal status,1:defense status',
  log_created DATETIME(6) NOT NULL COMMENT 'create datetime',
  log_modified DATETIME(6) NOT NULL COMMENT 'modify datetime',
  UNIQUE KEY ux_undo_log (xid, branch_id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';

客户端关键配置(application.yml):

seata:
  enabled: true
  application-id: seata-at-demo
  tx-service-group: demo_tx_group
  service:
    vgroup-mapping:
      demo_tx_group: default
    grouplist:
      default: 172.23.0.2:8091
  registry:
    type: file
  config:
    type: file
  data-source-proxy-mode: AT

💡 说明:registry.type: file 时客户端通过 service.grouplist 直连 TC 地址,将 default: <TC_IP>:8091 改为你的服务器 IP。业务方法加 @GlobalTransactional 注解(注意:必须通过 Spring 代理调用,同类内部 this.xxx() 自调用会导致注解失效,实测踩坑见第十二章 Q1)。

执行结果(客户端真实输出):

>>> [事务前] demo_account -> {id=1, money=1000}
>>> [分支1] UPDATE demo_account SET money = money + 500 WHERE id = 1
>>> [分支1执行后] demo_account -> {id=1, money=1500}
>>> [分支1执行后] undo_log 行数 -> 1
>>> 捕获业务异常(模拟第二笔操作失败):second operation failed on purpose
rollback status: Rollbacked
>>> [回滚后] demo_account -> {id=1, money=1000}
>>> [回滚后] undo_log 行数 -> 0

TC 侧同步日志(/root/logs/seata/seata-server.8091.all.log 节选):

receive msg[single]: BranchRegisterRequest{xid='172.23.0.2:8091:1135741007761358867', branchType=AT, resourceId='jdbc:mysql://seata-db:3306/seata_demo', lockKey='demo_account:1', ...}
Register branch successfully, xid = 172.23.0.2:8091:1135741007761358867, branchId = 1135741007761358869
Rollback global transaction successfully, xid = 172.23.0.2:8091:1135741007761358867

判定标准:分支期间数据变化 1000→1500、undo_log 出现 1 行前后镜像;异常触发回滚后 money 恢复 1000、undo_log 清零、客户端报 Rollbacked、TC 日志有 Rollback global transaction successfully。四项全部满足即安装验证通过。

十一、(可选)namingserver 控制台

2.6.0 控制台 UI 不再内嵌于 seata-server,改由发行包内的 seata-namingserver 承载(默认端口 8081)。实测它需要 JDK 25+:

java.lang.UnsupportedClassVersionError: org/apache/seata/namingserver/NamingserverApplication
  has been compiled by a more recent version of the Java Runtime (class file version 69.0),
  this version of the Java Runtime only recognizes class file versions up to 61.0

用 JDK 25 启动(以 Eclipse Temurin JRE 25 解压到 /opt/jre25 为例):

cd /opt/seata/seata-namingserver
JAVA_HOME=/opt/jre25 PATH=/opt/jre25/bin:$PATH nohup bash bin/seata-namingserver.sh > /tmp/ns.log 2>&1 &
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/

实测输出:

200

控制台账号密码在 seata-namingserver/conf/application.yml 的 console.user 下配置(默认空,本文设为 admin/q1w2e3r4),登录接口实测:

curl -s -X POST http://127.0.0.1:8081/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}'

实测输出(节选):

{"success":true,"error":null,"data":"eyJhbGciOiJIUzUxMiJ9...."}

⚠️ 已知问题:把 seata-server 的 seata.registry.type 切为 seata(注册到 namingserver)时,实测注册/注销请求返回 401(服务端日志 instance has been unregistered unsuccessfully:401),2.6.0 该链路认证存在兼容问题。生产注册中心建议使用 nacos/etcd3 等成熟方案,namingserver 当前更适合仅作控制台使用。

十二、常见问题(FAQ)

Q1:加了 @GlobalTransactional 但事务完全不生效(TC 无任何 begin 日志)? 最常见原因是同类内部方法自调用绕过了 Spring AOP 代理:run(){ this.doBusiness(); } 中的 @GlobalTransactional 不会生效。实测确认:改用注入的独立 Service Bean 调用(或 AopContext.currentProxy())后,TC 立即出现 begin new global transaction 与分支注册日志。

Q2:客户端报 ExceptionInInitializerError / NoClassDefFoundError(jackson 相关)? seata-spring-boot-starter 2.6.0 写 undo_log 的前后镜像序列化依赖 jackson,但官方 starter 不强制传递。需显式引入:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

实测两个依赖缺一不可:缺 databind 报 NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException,缺 jsr310 报 ExceptionInInitializerError(JacksonUndoLogParser 静态初始化失败,涉及 LocalDateTime 序列化)。

Q3:db 模式启动失败,报 The driver {com.mysql.cj.jdbc.Driver} cannot be found in the path /opt/seata/seata-server/lib/jdbc? 官方包不含驱动。下载 mysql-connector-j-8.4.0.jar 放入 /opt/seata/seata-server/lib/jdbc/(见 8.2 节)后重启即可。实测这是 db 模式必踩的第一个坑。

Q4:sh bin/seata-server.sh 报 Bad substitution? 脚本使用了 bash 特有语法,系统 /bin/sh(dash)解释不了。统一用 bash bin/seata-server.sh 执行。

Q5:启动日志出现 not support metrics exporter type: prometheus 或端口 9898 占用? 默认 metrics 导出未启用该类型,可忽略;若配置了 prometheus 导出而 9898 被旧进程占用(多开 seata-server 的典型现象),ps -ef | grep seata-server 清理重复进程后重启。

十三、卸载与清理

bash bin/seata-server.sh stop
systemctl disable seata-server --now
rm -rf /opt/seata
rm -rf /root/logs/seata

db 模式如需彻底清理,删除 seata 库:

mysql -h seata-db -uroot -pq1w2e3r4 -e "DROP DATABASE seata;"

十四、参考链接