Get into the habit of writing together! This is the third day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .
foreword
After reading this article you will learn the following:
- Seat
- Seata Server Deployment
- Seata Transaction Grouping
It will be easier to understand if you know the following:
This article is an applied article and will not elaborate too much theoretical knowledge
Terminology Analysis
The following terms will be used in this deployment:
- Seata Server: Seata server, officially called transaction coordinator TC (Transaction Coordinator ) , deployed separately
- Seata Client: Seata client, officially called Resource Manager RM (Resource Manager ), integrated with business systems
Official Glossary: Seata Glossary
Technical selection
Seata has a variety of deployment schemes, the following methods are recommended for the production environment: registration center + configuration center + database
The corresponding technology stack is as follows:
- Registration Center: Nacos
- Configuration Center: Nacos
- Database: MySQL 8.0
Deploy Seata Server
Initialize the database
Create database seata-server and corresponding access user seata
Use the official database script for initialization: seata/script/server/db at develop
Supports Oracle and PostgreSQL in addition to MySQL
custom configuration file
Refer to the official deployment documentation: Quickly deploy Seata Server with Docker compose
编写服务端配置文件registry.conf
:
registry {
type = "nacos"
nacos {
# 服务名称
application = "seata-server"
serverAddr = "127.0.0.1:8848"
# 命名空间ID
namespace = "spring-cloud-development"
group = "SEATA_GROUP"
# 集群名称
cluster = "default"
}
}
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = "spring-cloud-development"
group = "SEATA_GROUP"
# 配置文件dataId
dataId: "seata-server.properties"
}
}
复制代码
在nacos中增加配置seata-server.properties
, 调整为数据库模式:
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata-server?useUnicode=true&characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
store.db.user=seata
store.db.password=seata
复制代码
注意: 配置的dataId和group应与registry.conf
中的一致
使用docker-compose启动
对docker-compose不再赘述, 可阅读前言中的官方文档
编写docker-compose.yaml
:
# 根据自己的docker版本选择对应的version
version: "3.1"
services:
seata-server:
image: seataio/seata-server:1.4.2
hostname: seata-server
ports:
- "8091:8091"
environment:
- SEATA_PORT=8091
- SEATA_IP=127.0.0.1
# 此处有坑
- SEATA_CONFIG_NAME=file:/root/seata-config/registry
volumes:
# 此处有坑
- "./seata-server/config:/root/seata-config"
复制代码
这里有两个因为笔者不熟悉docker产生的坑:
环境变量SEATA_CONFIG_NAME
, 指的是容器内部的环境
所以路径file:/root/seata-config/registry
是指, 服务端读取的配置文件registry.conf
为容器内部的/root/seata-config/registry.conf
并非我们本机的/root/seata-config/registry
所以我们要将自己写的配置文件映射到其内部中, 即后面一个坑: "./seata-server/config:/root/seata-config"
它的含义是将本机路径./seata-server/config
映射到容器内部路径/root/seata-config
综上, 我们需要完成的操作是:
- 在
docker-compose.yaml
目录下创建seata-server/config
目录 - 将
registry.conf
文件放置到${docker-compose.yaml目录}/seata-server/config
- 运行命令
docker-compose up -d
如果您遇到了io.seata.common.exception.NotSupportYetException: config type can not be null
, 请仔细阅读上述内容
业务系统集成Seata Client
初始化数据库
在业务系统中增加undo_log
表:
-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
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;
复制代码
自定义配置文件
在nacos中增加客户端公共配置文件seata-client.properties
:
seata.registry.type=nacos
seata.registry.nacos.server-addr=127.0.0.1:8848
seata.registry.nacos.namespace=spring-cloud-development
seata.registry.nacos.group=SEATA_GROUP
seata.registry.nacos.application=seata-server
seata.config.type=nacos
seata.config.nacos.server-addr=127.0.0.1:8848
seata.config.nacos.namespace=spring-cloud-development
seata.config.nacos.group=SEATA_GROUP
复制代码
注意: 客户端配置的group应与服务端配置相同
引入启动类依赖
按照Seata部署指南推荐的方式在pom.xml
中引入依赖spring-cloud-starter-alibaba-seata
:
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>最新版</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<version>2.2.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
复制代码
之后再引入上一节中的客户端配置即可:
spring:
cloud:
nacos:
config:
shared-configs:
- data-id: seata-client.properties
group: SEATA_GROUP
复制代码
事务分组
想要学会一个概念, 最重要的是了解为什么要使用它
Looking back at the initial concept, Seata Server is the transaction coordinator TC ( Transaction Coordinator )
That is to say, it plays a crucial role in distributed transactions
But how did it hang? Or did the network fluctuate?
Therefore, transaction grouping can actually be understood as Seata Server cluster grouping, which is for the high availability of TC
Seata Server Configuration
The server needs to clarify its own group name and modify the registry.conf
file:
registry {
nacos {
# Seata Server所属集群名称为dev
cluster = "dev"
}
}
复制代码
According to the official document Seata transaction grouping , there is a pit here
You need to add a configuration of the transaction group name corresponding to the cluster name in nacos
Take the above cluster as an example, you need to add service.vgroup-mapping.${分组名}
configuration, the content is the cluster name:dev
The reason lies RegistryService
in the following code:
public interface RegistryService<T> {
String PREFIX_SERVICE_MAPPING = "vgroupMapping.";
String PREFIX_SERVICE_ROOT = "service";
String CONFIG_SPLIT_CHAR = ".";
default String getServiceGroup(String key) {
// 假设分组名为group-dev
// 会在nacos中寻找dataId为service.vgroupMapping.group-dev的配置
key = PREFIX_SERVICE_ROOT + CONFIG_SPLIT_CHAR + PREFIX_SERVICE_MAPPING + key;
if (!SERVICE_GROUP_NAME.contains(key)) {
ConfigurationCache.addConfigListener(key);
SERVICE_GROUP_NAME.add(key);
}
return ConfigurationFactory.getInstance().getConfig(key);
}
}
复制代码
If the client encounterscan not get cluster name in registry config 'service.vgroupMapping.xx', please make sure registry config correct
Please read the above carefully
Seata Client Configuration
Add the following to the project configuration:
seata:
tx-service-group: group-dev
复制代码
The final effect is: the transaction group will use the TC with the group-dev
cluster namedev
Application scenarios
The official provides a good example, please refer to: Transaction Grouping and High Availability (seata.io)
Summarize
It's shallow on paper
Between understanding Seata and actually deploying Seata, there is a technical gap such as docker/nacos
Finally, summarize the overall process of using Seata:
- Deploy Seata Server
- group transactions
- Business system integration Seata Client
I'm Houtaroy, and it's a lifetime honor to have a single line of code that helps others