Microservice - Seata
# 应用场景
分布式事务
# 概念
# 角色
TC (Transaction Coordinator) - 事务协调者(Server) 维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器(Client) 定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器(Client) 管理分支事务处理的资源,与 TC 交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
# 配置
无论是 Server 端还是 Client 端都需要读取一个配置文件 seataServer.properties
(opens new window),最简单的方法是当然是存储在本地,当作为一个微服务项目,更多时候是存储在配置中心,而 Seata 作为 Spring Cloud Alibaba 的一员,首选必然是 Nacos。
笔记
Seata 的 Client 使用的配置中心不一定要与 Spring Cloud 的配置中心一致,可以是微服务用的 Consul,而 Seata 读取配置用的 Nacos,但一般没人这么做。
由于 Server 端和 Client 端共用一个配置文件,因此里面既有分别仅对 Server 端、Client 端作用域的,也有两者都有效的。
# Client 端配置中心
application.yml
seata:
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
group: 'SEATA_GROUP'
namespace: ''
username: 'nacos'
password: 'nacos'
# Server 端配置中心
seata:
config:
# support: nacos 、 consul 、 apollo 、 zk 、 etcd3
type: consul
nacos:
server-addr: 127.0.0.1:8848
namespace:
group: SEATA_GROUP
username:
password:
context-path:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
data-id: seataServer.properties
::: detail 1.5 以下配置
registry.conf
config {
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
username = "nacos"
password = "nacos"
}
}
:::
# 常用配置
store.mode
:事务存储配置,开发环境使用默认的 file 即可,生产环境可设为 db,并配置对应的链接参数。
参数配置 | Apache Seata (opens new window)
# 通信
Seata Client 端是如何与 Server 端通信的?
最简单的方法是在本地配置文件( type: file
)中写死 Server 端的连接信息,具体参考 application.yml (opens new window) 中 registry
部分。
作为一个微服务项目,显然这种方法同样是不优雅的,因此应当使用注册中心来维护 Server 端的 IP 信息,而 Seata 作为 Spring Cloud Alibaba 的一员,首选必然还是 Nacos。
笔记
如配置中心一样,Seata 的 Client 使用的注册中心不一定要与 Spring Cloud 的注册中心一致,可以是微服务用的 Consul,而 Seata 用的 Nacos,但一般没人这么做。
# 事务分组
seata 有别于一般微服务间调用直接使用服务名的方式,seata 使用了一个叫 事务分组
的概念,在 client 与 server 之间插入了一个映射关系,需要通过 事务分组名
拿到对应的 seata集群名称
,通过一定的处理(不同的注册中心实现不同)得到真正的 服务名
,这是才能通过 服务名
从注册中心获取到 seata TC 服务列表。实际操作见下文配置。
笔记
seata 针对不同的注册中心,通过映射获取 TC 服务列表的方式不同,实践中发现注册中心为 nacos 时:
seata.service.vgroup-mapping.事务分组名=集群名称
这里映射的 集群名称
实际为 nacos 中的 clusterName
,当 server 节点注册到注册中心时, cluster
属性对应的时 nacos 的 clusterName
,通过 nacos 的 服务管理 - 服务列表 - seata-server(服务名) - 详情
,在此页面抓包可知节点的属性有一个 clusterName
字段,即为 seata 的 cluster
。
参考:
- 事务分组介绍 | Apache Seata (opens new window)
- 事务分组集成注册中心后的作用?・Issue #5505・apache/incubator-seata (opens new window)
# Client 端配置注册中心
application.yml
seata:
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group : "SEATA_GROUP"
namespace: ""
username: ""
password: ""
context-path: ""
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key: ""
#secret-key: ""
tx-service-group: my_test_tx_group
service:
vgroup-mapping:
my_test_tx_group: default
tx-service-group
:声明了服务所属的事务分组,默认为default_tx_group
seata.service.vgroup-mapping.事务分组名=集群名称
:这个属性应该配置在 client 和 server 共用的存在配置中心的seataServer.properties
文件中。在上述的配置中即为my_test_tx_group
事务分组对应 default 名为default
的 seata TC 集群。
# Server 端配置注册中心
conf/application.yaml
seata:
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
cluster: default
username:
password:
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key: ""
#secret-key: ""
cluster
:注册的集群名为default
。
# 存储
Server 端存储模式(store.mode)现有 file、db、redis、raft
file 模式无需改动,直接启动即可,file 模式为单机模式,全局事务会话信息内存中读写并异步 (默认) 持久化本地文件 root.data,性能较高;
raft 模式部署方式请访问专门部署文档 (opens new window)
db 模式为高可用模式,全局事务会话信息通过 db 共享,相应性能差些;
redis 模式 Seata-Server 1.3 及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置合适当前场景的 redis 持久化配置。
笔记
对于开发环境使用 file 模式足够,生产环境更多使用 db 模式
# 部署 Server 端
参考:Kubernetes 部署 | Apache Seata (opens new window)
笔记
这里个大坑:
1.5.x 版本的 seata-server 已经改造成 springboot,不再读取 conf 配置文件
官方文档直到当前最新的 2.0 文档仍然使用的 registry.conf,实际上需要 application.yml
来配置
参考:
nacos 配置中心 + nacos 注册中心 + file 存储,使用 kubernetes 部署
# Nacos
创建配置文件 seataServer.properties
(opens new window),创建位置对应下面的 application.yml
文件。
# ConfigMap
seata-server-config
在 git 仓库找到对应版本的 application.yml
文件,如 incubator-seata/server/src/main/resources/ application.yml
at v1.7.1 · apache/incubator-seata (opens new window)。
application.yml,根据实际修改,参考配置application.example.yml
(opens new window):
# Copyright 1999-2019 Seata.io Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${log.home:${user.home}/logs/seata}
extend:
logstash-appender:
destination: 127.0.0.1:4560
kafka-appender:
bootstrap-servers: 127.0.0.1:9092
topic: logback_to_logstash
console:
user:
username: seata
password: seata
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: file
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: file
store:
# support: file 、 db 、 redis
mode: file
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login
# Deployment
seata-server
- 镜像:
seataio/seata-server:{latest_version}
- 挂载
seata-config(ConfigMap)/application.yml:/root/seata-config
(伪代码)
- 挂载
# Service
- 7091:WEB 管理端
- 8091:通信端口