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

本文关注点主要放在了分布式框架Seata及对其服务进行docker部署上,如果想要了解Nacos,可以通过以下链接了解:

Nacos官方Git地址:https://github.com/alibaba/nacos

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进行部署_第1张图片
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进行部署_第2张图片
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过程中的记录,有不同观点和错误之处,请指出。

你可能感兴趣的:(使用springCloud+Seata+Nacos实现分布式事务,并通过docker进行部署)