有来实验室|第一篇:Seata1.5.2版本部署和开源全栈商城订单支付业务实战(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 有来实验室|第一篇:Seata1.5.2版本部署和开源全栈商城订单支付业务实战(一)

在线体验:Seata实验室


微信图片_20230710090430.gif


一. 前言

相信 youlai-mall 的实验室大家有曾在项目中见到过,但应该都还处于陌生的阶段,毕竟在此之前实验室多是以概念般的形式存在,所以我想借着此次的机会,对其进行一个详细的说明。


实验室模块的建立初衷和开源项目的成立一致的,都是为了提升开发成员的技术能力,只不过开源项目是从技术栈广度上(全栈),而实验室则是从技术栈深度方面切入,更重要的它是一种更深刻而又高效的学习方式。为什么能够这么说?因为实验室是结合真实的业务场景把 Seata 分布式事务能力可视化,通过现象去看本质(原理和源码),不再是被动式输入的短期记忆学习。


实验室未来计划是将工作和面试常见的中间件(Spring、MyBatis、Redis、Seata、MQ、MySQL、ES等)做进来,本篇就以 Seata 为例正式为有来实验室拉开一个序幕。


二. Seata 概念

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。


术语

TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。

TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

三. Seata 服务端部署

中间件声明

中间件 版本 服务器IP 端口

Seata 1.5.2 192.168.10.100 8091、7091

Nacos 2.0.3 192.168.10.99 8848

MySQL 8.0.27 192.168.10.98 3306

官方链接

名称 地址

文档 http://seata.io/zh-cn/

源码 https://github.com/seata/seata

MySQL脚本 https://github.com/seata/seata/blob/1.5.2/script/server/db/mysql.sql

Seata外置配置 https://github.com/seata/seata/blob/1.5.2/script/config-center/config.txt

Seata 数据库

Seata 表结构MySQL脚本在线地址: https://github.com/seata/seata/blob/1.5.2/script/server/db/mysql.sql


执行以下脚本完成 Seata 数据库创建和表的初始化:


-- 1. 执行语句创建名为 seata 的数据库

CREATE DATABASE seata DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;


-- 2.执行脚本完成 Seata 表结构的创建

use seata;


-- the table to store GlobalSession data

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_status_gmt_modified` (`status` , `gmt_modified`),

   KEY `idx_transaction_id` (`transaction_id`)

) ENGINE = InnoDB

 DEFAULT CHARSET = utf8mb4;


-- the table to store BranchSession data

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(6),

   `gmt_modified`      DATETIME(6),

   PRIMARY KEY (`branch_id`),

   KEY `idx_xid` (`xid`)

) ENGINE = InnoDB

 DEFAULT CHARSET = utf8mb4;


-- the table to store lock data

CREATE TABLE IF NOT EXISTS `lock_table`

(

   `row_key`        VARCHAR(128) NOT NULL,

   `xid`            VARCHAR(128),

   `transaction_id` BIGINT,

   `branch_id`      BIGINT       NOT NULL,

   `resource_id`    VARCHAR(256),

   `table_name`     VARCHAR(32),

   `pk`             VARCHAR(36),

   `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',

   `gmt_create`     DATETIME,

   `gmt_modified`   DATETIME,

   PRIMARY KEY (`row_key`),

   KEY `idx_status` (`status`),

   KEY `idx_branch_id` (`branch_id`),

   KEY `idx_xid_and_branch_id` (`xid` , `branch_id`)

) ENGINE = InnoDB

 DEFAULT CHARSET = utf8mb4;


CREATE TABLE IF NOT EXISTS `distributed_lock`

(

   `lock_key`       CHAR(20) NOT NULL,

   `lock_value`     VARCHAR(20) NOT NULL,

   `expire`         BIGINT,

   primary key (`lock_key`)

) ENGINE = InnoDB

 DEFAULT CHARSET = utf8mb4;


INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);


Seata 配置

这里采用 Nacos 作为配置中心的方式,所以需要把 Seata 的外置配置 放置在Nacos上


1. 获取 Seata 外置配置

Seata 外置配置在线地址:https://github.com/seata/seata/blob/1.5.2/script/config-center/config.txt


完整配置如下:


#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html

#Transport configuration, for client and server

transport.type=TCP

transport.server=NIO

transport.heartbeat=true

transport.enableTmClientBatchSendRequest=false

transport.enableRmClientBatchSendRequest=true

transport.enableTcServerBatchSendResponse=false

transport.rpcRmRequestTimeout=30000

transport.rpcTmRequestTimeout=30000

transport.rpcTcRequestTimeout=30000

transport.threadFactory.bossThreadPrefix=NettyBoss

transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker

transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler

transport.threadFactory.shareBossWorker=false

transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector

transport.threadFactory.clientSelectorThreadSize=1

transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread

transport.threadFactory.bossThreadSize=1

transport.threadFactory.workerThreadSize=default

transport.shutdown.wait=3

transport.serialization=seata

transport.compressor=none


#Transaction routing rules configuration, only for the client

service.vgroupMapping.default_tx_group=default

#If you use a registry, you can ignore it

service.default.grouplist=127.0.0.1:8091

service.enableDegrade=false

service.disableGlobalTransaction=false


#Transaction rule configuration, only for the client

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

client.rm.sagaBranchRegisterEnable=false

client.rm.sagaJsonParser=fastjson

client.rm.tccActionInterceptorOrder=-2147482648

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.tm.interceptorOrder=-2147482648

client.undo.dataValidation=true

client.undo.logSerialization=jackson

client.undo.onlyCareUpdateColumns=true

server.undo.logSaveDays=7

server.undo.logDeletePeriod=86400000

client.undo.logTable=undo_log

client.undo.compress.enable=true

client.undo.compress.type=zip

client.undo.compress.threshold=64k

#For TCC transaction mode

tcc.fence.logTableName=tcc_fence_log

tcc.fence.cleanPeriod=1h


#Log rule configuration, for client and server

log.exceptionRate=100


#Transaction storage configuration, only for the server. The file, DB, and redis configuration values are optional.

store.mode=file

store.lock.mode=file

store.session.mode=file

#Used for password encryption

store.publicKey=


#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.

store.file.dir=file_store/data

store.file.maxBranchSessionSize=16384

store.file.maxGlobalSessionSize=512

store.file.fileWriteBufferCacheSize=16384

store.file.flushDiskMode=async

store.file.sessionReloadReadSize=100


#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.

store.db.datasource=druid

store.db.dbType=mysql

store.db.driverClassName=com.mysql.jdbc.Driver

store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true

store.db.user=username

store.db.password=password

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


#These configurations are required if the `store mode` is `redis`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `redis`, you can remove the configuration block.

store.redis.mode=single

store.redis.single.host=127.0.0.1

store.redis.single.port=6379

store.redis.sentinel.masterName=

store.redis.sentinel.sentinelHosts=

store.redis.maxConn=10

store.redis.minConn=1

store.redis.maxTotal=100

store.redis.database=0

store.redis.password=

store.redis.queryLimit=100


#Transaction rule configuration, only for the server

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.xaerNotaRetryTimeout=60000

server.session.branchAsyncQueueSize=5000

server.session.enableBranchAsyncRemove=false

server.enableParallelRequestHandle=false


#Metrics configuration, only for the server

metrics.enabled=false

metrics.registryType=compact

metrics.exporterList=prometheus

metrics.exporterPrometheusPort=9898


2. 导入配置至 Nacos

在 Nacos 默认的 public 命名空间下 ,新建配置 Data ID 为 seataServer.properties ,Group 为 SEATA_GROUP 的配置,并将Seata外置配置config.txt 内容复制进来

微信图片_20230710090512.png微信图片_20230710090517.png





3. 修改 Seata 外置配置

仅需修存储模式为db以及对应的db连接配置


# 修改store.mode为db,配置数据库连接

store.mode=db

store.db.dbType=mysql

store.db.driverClassName=com.mysql.cj.jdbc.Driver

store.db.url=jdbc:mysql://192.168.10.98:3306/seata?useUnicode=true&rewriteBatchedStatements=true

store.db.user=root

store.db.password=123456


store.mode=db 存储模式选择为数据库

192.168.10.98 MySQL主机地址

store.db.user=root 数据库用户名

store.db.password=123456 数据库密码

Seata 部署

Seata 官方部署文档:https://seata.io/zh-cn/docs/ops/deploy-by-docker.html


1. 获取应用配置

按照官方文档描述使用自定义配置文件的部署方式,需要先创建临时容器把配置copy到宿主机


创建临时容器


docker run -d --name seata-server -p 8091:8091 -p 7091:7091 seataio/seata-server:1.5.2

1

创建挂载目录


mkdir -p /mnt/seata/config

1

复制容器配置至宿主机


docker cp seata-server:/seata-server/resources/ /mnt/seata/config

1

注意复制到宿主机的目录,下文启动容器需要做宿主机和容器的目录挂载

微信图片_20230710090606.png



过河拆桥,删除临时容器


docker rm -f seata-server

1

2. 修改启动配置

在获取到 seata-server 的应用配置之后,因为这里采用 Nacos 作为 seata 的配置中心和注册中心,所以需要修改 application.yml 里的配置中心和注册中心地址,详细配置我们可以从 application.example.yml 拿到。


application.yml 原配置

微信图片_20230710090609.png


修改后的配置(参考 application.example.yml 示例文件),以下是需要调整的部分,其他配置默认即可


seata:

 config:

   type: nacos

   nacos:

     server-addr: 192.168.10.99:8848

     namespace:

     group: SEATA_GROUP

     data-id: seataServer.properties

 registry:

   type: nacos

   preferred-networks: 30.240.*

   nacos:

     application: seata-server

     server-addr: 192.168.10.99:8848

     namespace:

     group: SEATA_GROUP

     cluster: default

 # 存储模式在外置配置(Nacos)中,Nacos 配置加载优先级大于application.yml,会被application.yml覆盖,所以此处注释

 #store:

  #mode: file


**192.168.10.99 ** 是Nacos宿主机的IP地址,Docker部署别错填 localhost 或Docker容器的IP(172.17. * . *)

namespace nacos命名空间id,不填默认是public命名空间

data-id: seataServer.properties Seata外置文件所处Naocs的Data ID,参考上小节的 导入配置至 Nacos

group: SEATA_GROUP 指定注册至nacos注册中心的分组名

cluster: default 指定注册至nacos注册中心的集群名

3. 启动容器

docker run -d --name seata-server --restart=always  \

-p 8091:8091 \

-p 7091:7091 \

-e SEATA_IP=192.168.10.100 \

-v /mnt/seata/config:/seata-server/resources \

seataio/seata-server:1.5.2


/mnt/seata/config Seata应用配置挂载在宿主机的目录


**192.168.10.100 ** Seata 宿主机IP地址


在 nacos 控制台 的 public 命名空间下服务列表里有 seata-server 说明部署启动成功


微信图片_20230710090637.png


如果启动失败或者未注册到 nacos , 基本是粗心的结果,请仔细检查下自己 application.yml 的注册中心配置或查看日志


docker logs -f --tail=100 seata-server

1

以上就完成对 Seata 服务端的部署和配置,接下来就是 SpringBoot 与 Seata 客户端的整合。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
IDE Java Linux
Seata常见问题之重新打包以单独用jar来部署如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
268 1
|
7月前
|
SQL Oracle 关系型数据库
seata版本问题之码云拉取代码异常如何解决
Seata是一款开源的分布式事务解决方案,旨在提供高效且无缝的分布式事务服务;在集成和使用Seata过程中,开发者可能会遇到不同的异常问题,本合集针对Seata常见异常进行系统整理,为开发者提供详细的问题分析和解决方案,助力高效解决分布式事务中的难题。
283 6
|
7月前
|
关系型数据库 Linux Nacos
Linux 环境下使用 Docker 部署 Seata 1.7.1 (图文教程)
Linux 环境下使用 Docker 部署 Seata 1.7.1 (图文教程)
|
7月前
|
存储 Java Nacos
Seata常见问题之springboot 2.3.7 和高版本 seata 2.0.0,1.6.1不兼容如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
921 0
|
7月前
|
关系型数据库 Java Nacos
Seata的部署和集成
部署Seata的tc-server
|
2月前
|
前端开发 Java API
Apache Seata(incubating) 首个版本重磅发布!
2.1.0 是 Seata 进入 Apache 基金会的第一个 Release Version。此次发布将 io.seata 包名更改为 org.apache.seata。除了按原有的 Roadmap 技术演进外,2.1.0 进行了大量兼容性工作,实现了 API、数据和协议的兼容。用户无需修改原有的 API 和配置,即可实现到 Apache 版本的平滑升级。
125 16
Apache Seata(incubating) 首个版本重磅发布!
|
4月前
|
Java Nacos Docker
"揭秘!Docker部署Seata遇上Nacos,注册成功却报错?这些坑你不得不防!一网打尽解决秘籍,让你的分布式事务稳如老狗!"
【8月更文挑战第15天】在微服务架构中,Nacos搭配Seata确保数据一致性时,Docker部署Seata后可能出现客户端连接错误,如“can not connect to services-server”。此问题多由网络配置不当、配置文件错误或版本不兼容引起。解决策略包括:调整Docker网络设置确保可达性;检查并修正`file.conf`和`registry.conf`中的Nacos地址和端口;验证Seata与Nacos版本兼容性;修改配置后重启服务;参考官方文档和最佳实践进行配置。通过这些步骤,能有效排除故障,保障服务稳定运行。
359 0
|
7月前
|
Kubernetes Cloud Native API
欢迎报名 Apache Seata (incubating) 开源之夏
Apache Seata (incubating) 邀请学生参加 2024 年开源之夏活动,报名时间为 4 月 30 日至 6 月 3 日。该项目旨在培养分布式事务领域的开发者,参与者将远程协作并有机会获得奖金。
1335 19
|
7月前
|
Java 数据库连接 API
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
146 0
|
7月前
|
开发框架 Java 数据库连接
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)(下)
分布式事物【XA强一致性分布式事务实战、Seata提供XA模式实现分布式事务】(五)-全面详解(学习总结---从入门到深化)
115 0