Docker+SEATA+Nacos+SpringBoot实现分布式事务

发布时间 2024-01-02 20:47:11作者: 小庄的blog

Docker+SEATA+Nacos+SpringBoot实现分布式事务

1. 服务端

示例SEATA版本:1.6.1

1.1. 配置的创建

docker pull seataio/seata-server:1.6.1
# 这里的运行只是为了获取里面的配置,将配置拿出来到宿主机后进行配置再删除容器再使用配置好的配置进行启动
docker run -d -p 8091:8091 -p 7091:7091  --name seata-server seataio/seata-server:1.6.1
mkdir -p /docker-app/seata/config
docker cp seata-server:/seata-server/resources /docker-app/seata/config

这里就可以在宿主机的/docker-app/seata/config 有以下文件了:

application.example.yml  application.yml  banner.txt  io  logback  logback-spring.xml  lua  META-INF  README.md  README-zh.md

1.2. 配置application.yml

在配置之前需要了解一下docker的网络,下面的配置需要容器与容器的通信

可以知道容器所在局域网是在docker0上,而docker0又可以看作是容器宿主机上,由于容器的端口,如nacos的8848就暴露在宿主机上,所以我们可以通过docker0宿主机ip:8848可以访问到。
在linux上通过ip addr 可以知道docker0宿主机ip是172.17.0.1.

配置application.yml :

server:
  port: 7091

spring:
  application:
    name: seata-server # 在nacos中配置的seata-server的名称

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${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: nacos # 使用nacos作为配置中心
    preferred-networks: 
    nacos:
      server-addr: 172.17.0.1:8848 # seata访问nacos ,属于容器与容器的访问
      namespace: seata # 指定配置文件三步曲:第一项
      group: SEATA_GROUP # 指定配置文件三步曲:第二项
      data-id: seataServer.properties # 指定配置文件三步曲:第三项
      username: nacos
      password: nacos
      context-path:
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:  # 同register
      application: seata-server
      server-addr: 172.17.0.1:8848
      group: SEATA_GROUP
      namespace: seata
      cluster: default
      username: nacos
      password: nacos
      context-path:
#  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,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

1.3. SEATA配置先放到nacos config

下面需要用到的:

  1. SEATA1.6 配置集
    https://github.com/apache/incubator-seata/blob/1.6.1/script/config-center/config.txt

  2. SEATA 1.6配置->nacos config的执行脚本:
    https://github.com/apache/incubator-seata/blob/1.6.1/script/config-center/nacos/nacos-config.sh

从上面提供的链接获取并修改config.txt(修改下面所说的配置):

...
# 使用db而不是默认的file
store.mode=db
# 修改数据库配置信息,这里的数据库后面会导入
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=root
store.db.password=3333
...
# `事务分组配置项`:这里可以不用修改,但为了后面测试是否部署Ok,这里不使用默认的,修改为`guangzhou`
# 注意这里的写法可能你并不那么容易理解,它是这样的`service.vgroupMapping.<你的事务分组配置项>=default`
service.vgroupMapping.guangzhou=default

做法一: 在上面application.yml nacos配置中心指定了data-id

在上面application.yml nacos配置中心指定了data-id时, 那配置集以一个文件形式存在。

在上面配置application.yml中已经指定配置文件在seata命名空间下SEATA_GROUP分组下的seataServer.properties:

所以:将config.txt的全选粘贴到nacos 下面这个nacos配置项内:

image-20240102105212689

image-20240102105319863

等等,请你确认一下配置中Group是否为SEATA_GROUP !

做法2:在上面application.yml nacos配置中心没有指定了data-id

config.txt文件放到当前所在resources目录的上层,即/docker-app/seata/config下。
nacos-config.sh文件放到/docker-app/seata/config/resources目录下。

切换到nacos-config.sh文件目录执行:

chmod +x nacos-config.sh
# 注意这里的命名空间`seata` 与 命名空间下的分组`SEATA_GROUP`需要与application.yml配置的一致。
bash ./nacos-config.sh -h 127.0.0.1 -p 8848 -t seata -g SEATA_GROUP -u nacos -w nacos

那么你就可以看到配置集,每一条都是一个配置项。

image-20240102105955755

1.4. 数据库导入

在上面1.3 中我们指定了数据库,所以我们需要创建一个seata的数据库:

seata.sql:https://github.com/apache/incubator-seata/blob/1.6.1/script/server/db/mysql.sql

1.5. 启动SEATA

下面命令注释必读!!!

# 因为我们之前启动过SEATA,但之前我们只是为了获取里面的配置,这里才是真正
docker stop seata-server
docker rm seata-server

# 下面的`SEATA_IP`意义:
#  因为SEATA是在docker容器中的,那在真机上windows想要访问在虚拟机上的docker的窗口怎么办呢,到时候seata-server暴露给nacos注册中心的地址是docker0上的网段的容器ip,我们真机上的Java程序想要访问到它,seata-server暴露给nacos的服务地址应该是真机能访问到的,那只能是虚拟机(linux)的ip了,即分配给虚拟机的ip(通过在虚拟机`ip addr`的eth0的ip,得到下面的172.29.61.28)
docker run --name seata-server --restart=always \
        -p 8091:8091 \
        -p 7091:7091 \
        -e SEATA_IP=172.29.61.28 \
        -v /docker-app/seata/config/resources:/seata-server/resources  \
        seataio/seata-server:1.6.1

注意:你初次运行后是在前台运行,感觉挺好,可以看SEATA是否成功启动,如果在后台你直接Ctrl+C掉,再使用docker start seata-server 即可。

2. 客户端

pom.xml

如果SEATA版本与项目中引入的alibaba-cloud的版本对应(怎么知道?),直接使用:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

否则自已指定SEATA版本:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>seata-all</artifactId>
            <groupId>io.seata</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.6.1</version>
</dependency>

配置application.yml:

# .... 其它配置

# SEATA配置
seata:
  tx-service-group: guangzhou  # 我们修改了事务分组,所以这里也需要进行指定
  registry:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848 # 因为我使用的是WSL而不是VMware,如果是VMware需要指定虚拟机的ip
      application: seata-server
      username: nacos
      password: nacos
      group: SEATA_GROUP
      namespace: seata
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848 # 因为我使用的是WSL而不是VMware,如果是VMware需要指定虚拟机的ip
      username: nacos
      password: nacos
      namespace: seata  # 指定配置三步曲:配置所在的命名空间
      group: SEATA_GROUP  # 指定配置三步曲:配置所在的命名空间下的分组
      data-id:  seataServer.properties # 指定配置三步曲:配置所在的命名空间下的分组的配置文件名

配置好后,就可以启动项目了。如果不报错就是ok,就可以进行测试了

然后就像使用@Transactional 一样使用@GlobalTransactional ,注意@GlobalTransactional不需要依赖@EnableTransactionManagement 进行开启。