使用springCloud+Seata+Nacos实现分布式事务,并通过docker进行部署

本文关注点主要放在了分布式框架Seata及对其服务进行docker部署上,如果想要了解Nacos,可以通过以下链接了解:
Nacos官方Git地址:https://github.com/alibaba/nacos
【使用springCloud+Seata+Nacos实现分布式事务,并通过docker进行部署】Nacos官方文档地址:https://nacos.io/zh-cn/docs/
1、Seata相关文档及下载地址 Seata项目github地址:https://github.com/seata/seata
Seata中间件下载地址:https://github.com/seata/seata/releases
Seata中文官方文档:http://seata.io/zh-cn/
Seata官方示例:https://github.com/seata/seata-samples
2、Seata-server的部署 Seata支持两种事务日志存储方式:file和db模式。file模式是本地单机模式,无法支持HA,seata默认的也是这种模式。本文采取的是支持HA的db模式。
修改配置中心的配置 本文使用Nacos作为注册中心和配置中心。在官方链接 https://github.com/seata/seata/tree/1.1.0/script/config-center
中,该链接下的config.txt文件包含Seata常用的所有配置项,我们需要修改相关项目:

//该项修改为相应客户端中spring.cloud.alibaba.seata.tx-service-group的值,有多个客户端就添加多个 //例如在官方示例springcloud-nacos-seata中order-service和storage-service中spring.cloud.alibaba.seata.tx-service-group的值 //分别为order-service-group、storage-service-group,则需要将该项配置为service.vgroupMapping.order-service-group=default //和service.vgroupMapping.storage-service-group=default service.vgroupMapping.my_test_tx_group=default //事务日志存储模式 store.mode=db //数据库配置项 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver //配置自己相应的url,user,password store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true store.db.user=root store.db.password=root



在上面链接的/nacos目录下,有如下两个脚本: 使用springCloud+Seata+Nacos实现分布式事务,并通过docker进行部署
文章图片
image.png
使用其中一个脚本就可以将config.txt中配置项导入到指定的nacos中。
sh nacos-config.sh 127.0.0.1(nacos配置中心地址)或者Python nacos-config.py 127.0.0.1

导入成功后,在nacos管理后台可以看到配置项:

使用springCloud+Seata+Nacos实现分布式事务,并通过docker进行部署
文章图片
image.png 创建事务日志数据库 使用Seata的db模式需要创建相应的数据库seata以及对应的表
//全局事务表 global_table //分支子事务表 branch_table //全局锁表 lock_table

在官方链接 https://github.com/seata/seata/tree/develop/script/server/db
下有相应的脚本可以使用。
docker部署seata-sever 本文使用官方示例进行演示,官方的springcloud-nacos-seata示例中使用的是
com.alibaba.cloud spring-cloud-alibaba-seata 2.1.0.RELEASE io.seata seata-all 1.1.0

Seata不同版本的依赖关系可以查询官方文档进行了解。客户端使用的Seata 1.1.0版本,为了,选用seataio/seata-server:1.1.0镜像(这一点很重要,笔者刚开始拉取的是seataio/seata-server:latest镜像,客户端启动后一直报“no available service 'default' found, please make sure registry config correct”错误,很难发现的错误。)
docker compose启动 yaml文件示例:
version: "3" services: seata-server: image: seataio/seata-server:1.1.0 container_name: seata-server ports: - "8091:8091" environment: - SEATA_IP=127.0.0.1 //seata-server启动的IP,用于向注册中心注册使用,默认使用容器IP可能无法与客户端通讯 - SEATA_PORT=8091 //seata-server启动端口,默认8091

使用该yaml文件启动Seata-server,默认使用的是file模式,无法注册到nacos中和读取nacos中配置。需要进入到容器中修改/seata-server/resources目录下的registry.config文件:
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos"nacos { #修改为nacos的ip,默认使用容器ip,可能无法通讯 serverAddr = "127.0.0.1" namespace = "" cluster = "default" } eureka { serviceUrl = "http://localhost:8761/eureka" application = "default" weight = "1" } redis { serverAddr = "localhost:6379" db = "0" } zk { cluster = "default" serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 } consul { cluster = "default" serverAddr = "127.0.0.1:8500" } etcd3 { cluster = "default" serverAddr = "http://localhost:2379" } sofa { serverAddr = "127.0.0.1:9603" application = "default" region = "DEFAULT_ZONE" datacenter = "DefaultDataCenter" cluster = "default" group = "SEATA_GROUP" addressWaitTime = "3000" } file { name = "file.conf" } }config { # file、nacos 、apollo、zk、consul、etcd3 type = "nacos"nacos { #修改为nacos的ip,默认使用容器ip,可能无法通讯 serverAddr = "127.0.0.1" namespace = "" group = "SEATA_GROUP" } consul { serverAddr = "127.0.0.1:8500" } apollo { app.id = "seata-server" apollo.meta = "http://192.168.1.204:8801" namespace = "application" } zk { serverAddr = "127.0.0.1:2181" session.timeout = 6000 connect.timeout = 2000 } etcd3 { serverAddr = "http://localhost:2379" } file { name = "file.conf" } }

registry.conf修改完成只有重启容器即可(docker restart seata-server)。
为了便于后期的修改与维护,笔者将容器类的配置文件挂载到本地修改yaml文件为:
version: "3" services: seata-server: image: seataio/seata-server:1.1.0 container_name: seata-server volumes: - "d:/docker/docker-compose/seata/resources1.1.0:/seata-server/resources" ports: - "8091:8091" environment: - SEATA_IP=127.0.0.1 - SEATA_PORT=8091

客户端配置
  1. 在客户端配置中要注意的是,需要将registry.config文件放到resource目录下,并与服务端保持一致。
  2. spring.cloud.alibaba.seata.tx-service-group配置的值与服务端保持一致。
  3. 客户端数据库配置:每个服务都需要有相应的业务表和undo_log表,脚本可以查看链接下的readme。
容易踩到的坑及解决方法
  1. Seata不同版本依赖关系,可以查询官方文档了解。
  2. server端的配置service.vgroupMapping.my_test_tx_group=default,需要注意两点:
  • 在1.1.0版本前后的命名方式不同,之前为service.vgroup_mapping.my_test_tx_group=default
  • my_test_tx_group为spring.cloud.alibaba.seata.tx-service-group的值,不然会报“no available service 'null' found, please make sure registry config”。
  1. 使用容器部署时,配置nacos等注册中心和配置中心地址时,不要默认使用容器IP。
  2. 镜像版本与客户端版本保持一致。
本文是在笔者在配置Seata过程中的记录,有不同观点和错误之处,请指出。

    推荐阅读