Springboot-Sharding-Jdbc-Seata集成(四)环境准备

对待自己温柔一点。你只不过是宇宙的孩子,与植物、星辰没什么两样。


 一.概览

Seata的分布式事务解决方案是业务层面的解决方案,只依赖于单台数据库的事务能力。 Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的 分布式解决方案。 Seata框架中一个分布式事务包含3中角色:

  • Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
  • Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
  • Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。 

其中,TM是一个分布式事务的发起者和终结者,TC负责维护分布式事务的运行状态,而RM则负责本地事务的运行。

文档地址:https://seata.io/zh-cn/docs/overview/what-is-seata.html

官网下载地址:http://seata.io/zh-cn/blog/download.html 查看各版本

二.Seata的执行流程 

  • 1.TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID。
  • 2.XID 在微服务调用链路的上下文中传播。
  • 3.RM 向 TC 注册分支事务,接着执行这个分支事务并提交(重点:RM在第一阶段就已经执行了本地事务的提交/回滚),最后将执行结果汇报给TC。
  • 4.TM 根据 TC 中所有的分支事务的执行情况,发起全局提交或回滚决议。
  • 5.TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。

三.环境安装(Docker安装Seata)

1.创建Seata对应宿主机数据文件

宿主机创建配置文件目录,用于挂载文件,位置自定
##配置文件目录
mkdir /home/seata/seata-config
##日志文件目录
mkdir /home/seata/logs

2.拷贝Seata默认配置 

拉取镜像
docker pull seataio/seata-server:1.4.2
 
运行容器并获取配置
## 运行容器
docker run -it -d -p 13391:8091 \
-e SEATA_PORT=13391 \
--name seata1.4.2  seataio/seata-server:1.4.2
## 进入容器
docker exec -it 1e33b26152e1 /bin/bash
docker exec -it 1e33b26152e1 /bin/sh
docker exec -it 1e33b26152e1 bash
docker exec -it 1e33b26152e1 sh
## 将容器中的配置拷贝到/home/seata/ 自定义目录
docker cp seata1.4.2:/seata-server /home/seata/seata-s
## 完成后就会在/home/seata/出现容器的配置,我们现在可以将原来容器停止并删除
docker stop seata-server & docker rm seata-server

3.Seata配置文件

3.1.registry.conf

#seata服务, 将type从file改成nacos, 将seata服务配置进nacos
registry {
 
    type = "nacos"
    nacos {
        application = "seata-server" # seata注册到nacos的名称
        serverAddr = "IP:13348" # nacos注册中心地址
        group = "SEATA_GROUP"   # nacos注册中心的组名
        namespace = "85a8089c-4d4f-485d-b873-107e679528a6" # nacos注册中心的命名空间ID或者名称
        cluster = "default" # 
        username = "nacos"  # 账户
        password = "nacos"  # 密码
    }
    eureka {
        serviceUrl = "http://localhost:8761/eureka"
        application = "default"
        weight = "1"
    }
    redis {
        serverAddr = "localhost:6379"
        db = 0
        password = ""
        cluster = "default"
        timeout = 0
    }
    zk {
        cluster = "default"
        serverAddr = "127.0.0.1:2181"
        sessionTimeout = 6000
        connectTimeout = 2000
        username = ""
        password = ""
    }
    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:/root/seata-config/file.conf"
    }
}
 
# 配置
config {
    # 测试启动可用file;一般开发使用nacos配置
    #file、 nacos、 apollo、 zk、 consul、 etcd3
    type = "nacos"
 
    nacos {
      serverAddr = "IP:13348" # nacos 地址
      namespace = "85a8089c-4d4f-485d-b873-107e679528a6" # nacos 命名空间
      group = "SEATA_GROUP"  # nacos 组
      username = "nacos"
      password = "nacos"
    }
    consul {
        serverAddr = "127.0.0.1:8500"
    }
    apollo {
        appId = "seata-server"
        apolloMeta = "http://192.168.1.204:8801"
        namespace = "application"
    }
    zk {
        serverAddr = "127.0.0.1:2181"
        sessionTimeout = 6000
        connectTimeout = 2000
        username = ""
        password = ""
    }
    etcd3 {
        serverAddr = "http://localhost:2379"
    }
    file {
        # file.conf 配置文件所在路径;注意前缀是file:
        name = "file:/home/nacos/seata/seata-config/file.conf"
    }
}

3.2.file.conf

service {
   #vgroup->rgroup
   # file.conf文件这里如果seata版本大于1.1.0,一定写成vgroupMapping.sharding_jdbc_tx_group
   # 而不是 vgroup_mapping.sharding_jdbc_tx_group
   # sharding_jdbc_tx_group 是组名(可以配置多个)
   # vgroup_mapping.sharding_jdbc_tx_group = "default
   vgroupMapping.sharding_jdbc_tx_group = "default"
   #only support single node
   default.grouplist = "IP:13391"
   #degrade current not support
   enableDegrade = false
   #disable
   disable = false
   #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
   max.commit.retry.timeout = "-1"
   max.rollback.retry.timeout = "-1"
 }
#transaction log store, only used in seata-server
store {
  ## store mode: file、db、redis
  mode = "db" ## 原来为file
 
  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.cj.jdbc.Driver"
    ## 因为设置为db,所以需要选择数据库,这里设置数据库及密码,seata是需要创建的,默认的表是通过脚本运行得到的
    url = "jdbc:mysql://IP:13301/seata?serverTimezone=GMT%2B8"
    user = "root"
    password = "123456"
    minConn = 5
    maxConn = 305
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}

3.2.registry配置类型nacos时处理

①首先创建数据库seata(名字自定义);新建对应表结构;业务数据库中新建undo_log日志表

全局事务会话信息由3块内容构成,全局事务-->分支事务-->全局锁, 对应表global_table、branch_table、lock_table

-- seata.branch_table definition
 
CREATE TABLE `branch_table` (
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `resource_group_id` varchar(32) DEFAULT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `branch_type` varchar(8) DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `client_id` varchar(64) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime(6) DEFAULT NULL,
  `gmt_modified` datetime(6) DEFAULT NULL,
  PRIMARY KEY (`branch_id`) USING BTREE,
  KEY `idx_xid` (`xid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
 
 
-- seata.global_table definition
 
CREATE TABLE `global_table` (
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `status` tinyint(4) NOT NULL,
  `application_id` varchar(32) DEFAULT NULL,
  `transaction_service_group` varchar(32) DEFAULT NULL,
  `transaction_name` varchar(128) DEFAULT NULL,
  `timeout` int(11) DEFAULT NULL,
  `begin_time` bigint(20) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xid`) USING BTREE,
  KEY `idx_gmt_modified_status` (`gmt_modified`,`status`) USING BTREE,
  KEY `idx_transaction_id` (`transaction_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
 
 
-- seata.lock_table definition
 
CREATE TABLE `lock_table` (
  `row_key` varchar(128) NOT NULL,
  `xid` varchar(96) DEFAULT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `branch_id` bigint(20) NOT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `table_name` varchar(32) DEFAULT NULL,
  `pk` varchar(36) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`row_key`) USING BTREE,
  KEY `idx_branch_id` (`branch_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
 
-- dd.undo_log definition
 
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,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

3.4.上传config.txt配置到nacos

新建config.txt以及nacos-config.sh

touch config.txt -> 在对应目录中新建/home/seata/
 
touch nacos-config.sh -> 在对应目录中新建/home/seata/seata-config

①.config.txt

touch config.txt
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
service.vgroupMapping.my_test_tx_group=default # my_test_tx_group修改为自定义的组名;如果配置类型是file;和file.conf的service配置一致 
service.default.grouplist=ip:8091 #修改为seata的访问地址
service.enableDegrade=false
service.disableGlobalTransaction=false
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
store.mode=db
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100
store.db.datasource=druid
store.db.dbType=mysql # 修改为新建的seata数据库地址
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://ip:13301/seata?useUnicode=true
store.db.user=root
store.db.password=123456
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
store.redis.host=127.0.0.1
store.redis.port=6379
store.redis.maxConn=10
store.redis.minConn=1
store.redis.database=0
store.redis.password=null
store.redis.queryLimit=100
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

②.nacos-config.sh

#!/usr/bin/env bash
# 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.
 
while getopts ":h:p:g:t:u:w:" opt; do
	case $opt in
	h)
		host=$OPTARG
		;;
	p)
		port=$OPTARG
		;;
	g)
		group=$OPTARG
		;;
	t)
		tenant=$OPTARG
		;;
	u)
		username=$OPTARG
		;;
	w)
		password=$OPTARG
		;;
	?)
		echo " USAGE OPTION: $0 [-h host] [-p port] [-g group] [-t tenant] [-u username] [-w password] "
		exit 1
		;;
	esac
done
 
if [[ -z ${host} ]]; then
	host=localhost
fi
if [[ -z ${port} ]]; then
	port=8848
fi
if [[ -z ${group} ]]; then
	group="SEATA_GROUP"
fi
if [[ -z ${tenant} ]]; then
	tenant=""
fi
if [[ -z ${username} ]]; then
	username=""
fi
if [[ -z ${password} ]]; then
	password=""
fi
 
nacosAddr=$host:$port
contentType="content-type:application/json;charset=UTF-8"
 
echo "set nacosAddr=$nacosAddr"
echo "set group=$group"
 
failCount=0
tempLog=$(mktemp -u)
function addConfig() {
	curl -X POST -H "${contentType}" "http://$nacosAddr/nacos/v1/cs/configs?dataId=$1&group=$group&content=$2&tenant=$tenant&username=$username&password=$password" >"${tempLog}" 2>/dev/null
	if [[ -z $(cat "${tempLog}") ]]; then
		echo " Please check the cluster status. "
		exit 1
	fi
	if [[ $(cat "${tempLog}") =~ "true" ]]; then
		echo "Set $1=$2 successfully "
	else
		echo "Set $1=$2 failure "
		((failCount++))
	fi
}
 
count=0
for line in $(cat $(dirname "$PWD")/config.txt | sed s/[[:space:]]//g); do
	((count++))
	key=${line%%=*}
	value=${line#*=}
	addConfig "${key}" "${value}"
done
 
echo "========================================================================="
echo " Complete initialization parameters,  total-count:$count ,  failure-count:$failCount "
echo "========================================================================="
 
if [[ ${failCount} -eq 0 ]]; then
	echo " Init nacos config finished, please start seata-server. "
else
	echo " init nacos config fail. "
fi

.上传配置

在Linux 中执行 nacos-config.sh 推送信息,nacos服务对应13348端口启动否则执行不生效
 
sh nacos-config.sh -h IP -p 13348 -g SEATA_GROUP -t 85a8089c-4d4f-485d-b873-107e679528a6 -u nacos -w nacos 
 
-p 13348 -g SEATA_GROUP 端口 组
 
-t 85a8089c-4d4f-485d-b873-107e679528a6 命名空间
 
-u nacos -w nacos 账户密码 

④.成功就可以在nacos config看到

4.启动 

## 启动 端口必须是8091(暂时未发现问题)
## docker必须指定公网IP
docker run -it -d   -p 8091:8091 \
-v /home/nacos/seata/seata-config/registry.conf:/seata-server/resources/registry.conf \
-v /home/nacos/seata/seata-config/file.conf:/seata-server/resources/file.conf \
-v /home/nacos/seata/logs:/root/logs \
-e SEATA_IP=公网IP \
-e SEATA_PORT=8091 \
--name seata-server seataio/seata-server:1.4.2

nacos服务列表中可以看到

错误:搭建Seata问题汇总:
1.can not get cluster name in registry config 'service.vgroupMapping.account-service-fescar-service-group', please make sure registry config correct

1.1.把 vgroupMapping.my_test_tx_group = "default"

改成 vgroupMapping.account-service-fescar-service-group = "default"
1.2.dataId必须是service.vgroupMapping+分组

2.no available service found in cluster 'default', please make sure registry config correct and keep 
2.1.registry.nacos.applictopn= seata 在注册中心的名称application
3:注意
vgroupMapping.delivery-note-group = “seata-server”
seata-server.grouplist = “192.168.145.185:8091”
这个配置一定要注意,默认格式是:
vgroupMapping.事务分组名称 = “事务分组名值”
事务分组名值.grouplist= “127.0.0.1:8091”
这里特别注意,如果seata服务器是其他IP地址,这里事务分组名值绝对不能写default,如果写default,seata会忽略下面的事务分组名值.grouplist= "127.0.0.1:8091"这句话
直接给事务分组名值.grouplist的值设置为127.0.0.1:8091,从而导致我们设置自己的seata服务器不生效。

“慢慢大家会明白的,无法跟喜欢的人在一起,其实是人生的常态。”

猜你喜欢

转载自blog.csdn.net/qq_35731570/article/details/121393672
今日推荐