乐趣区

关于seata:seata整合nacos完成分布式的部署

一、背景

最近在学习 Seata,此处简略记录一下Seata Server 的分布式部署,其中的注册核心和配置核心应用 nacos 来实现,默认的 file 形式无奈实现分布式部署。其中 nocos 和 mysql 默认认为在机器上曾经部署好了。

二、部署机器

机器 ip 部署资源 机器类型
192.168.56.101 seata server 虚拟机
192.168.56.102 seata server 虚拟机
192.168.56.103 seata server 虚拟机
10.1.206.169 nacos / mysql 宿主机

三、部署步骤

1、在 seata 上创立命名空间

在 nacos 上创立 seata 的命名空间,须要记住的是 命名空间的 id,这个值在前期须要用到。

2、下载对应版本的 seata

下载解压:

# 下载
wget https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.zip
# 解压
unzip seata-server-1.4.2.zip
# 查看 seata 目录构造
tree seata -L 2
seata
└── seata-server-1.4.2
    ├── LICENSE
    ├── bin
    ├── conf(次要批改 registry.conf 配置文件)├── lib
    └── logs

3、单机启动

此处演示的是在 192.168.56.101 这台机器上配置的 seata server。

1、批改 seata 配置文件

配置文件地位:$seata_server_home/conf/registry.conf

$seata_server_home 这是是 seata server 的解压目录。

1、批改注册核心为 nacos

vi conf/registry.conf

registry {
  # file、nacos、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
      # 注册到 nacos 上的服务名
    application = "seata-server"
    # nacos 的地址
    serverAddr = "10.1.168.152:8847"
    # nacos 上的分组
    group = "SEATA_GROUP"
    # 命名空间,为上一步创立的
    namespace = "774a5264-662f-4e27-a885-8d0783e5f26a"
    # 集群,这个是事物分组的时候须要用到
    cluster = "default"
    # nacos 的用户名和明码
    username = "nacos"
    password = "nacos"
  }
}

2、批改配置核心为 nacos

vi conf/registry.conf

config {
  # file、nacos、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "10.1.168.152:8848"
    namespace = "774a5264-662f-4e27-a885-8d0783e5f26a"
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
    # 此处的这个 dataId 的值,须要在 nacos 上创立,前期须要导入配置到这个命名空间中
    dataId = "seataServer.properties"
  }
}

2、导入配置到 nacos 中

数据的存储模式应用 db,也能够应用 redis,应用 db 须要创立 4 张表global_tablebranch_tablelock_tabledistributed_lock

1、存储模式设置为 db,建表

建表语句为 https://github.com/seata/seat…

-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(`xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(`row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

CREATE TABLE IF NOT EXISTS `distributed_lock`
(`lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;

INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);

2、简化的配置

残缺的配置: https://github.com/seata/seata/tree/develop/script/config-center/config.txt

留神:

  • 此处指定的存储模式是 db,因而须要配置数据库连贯信息,指定的数据库须要存在 上一步 创立的表。
  • 此处配置了多个分组,也指定了多个集群

# 这个中央的事物分组能够配置多个,多个配置多行 
service.vgroupMapping.my_test_tx_group=default
service.vgroupMapping.product-service=hangzhou
service.vgroupMapping.order-service=hangzhou
# 指定存储模式为 db
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://10.1.168.152:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root

3、残缺的配置

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=true
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
service.default.grouplist=127.0.0.1:8091
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.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
store.mode=db
store.lock.mode=file
store.session.mode=file
store.publicKey=
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
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://10.1.168.152:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
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
server.distributedLockExpireTime=10000
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.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

4、导入到 nacos 中

3、启动 seata server

./seata-server.sh -h 192.168.56.101 -p 8091 -n 1
 -h: 注册到注册核心的 ip
 -p: Server rpc 监听端口
 -m: 全局事务会话信息存储模式,file、db、redis,优先读取启动参数 (Seata-Server 1.3 及以上版本反对 redis)
 -n: Server node,多个 Server 时,需辨别各自节点,用于生成不同区间的 transactionId,免得抵触
 -e: 多环境配置参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html

4、查看 seata server 列表

4、seata server 集群启动

1、拷贝 seata server 配置到 3 台机器上

已知,咱们下面的操作都是在 192.168.56.101 这台机器上操作的,那么咱们将 192.168.56.101 这台机器上的 seata 配置拷贝到 192.168.56.102 和 192.168.56.103,而后启动即可。

# 1、将 192.168.56.101 的 seata 配置拷贝到 102 和 103 上
scp -r /home/appuser/opt/seata/ appuser@192.168.56.102:/home/appuser/opt/
scp -r /home/appuser/opt/seata/ appuser@192.168.56.103:/home/appuser/opt/

通过上方 2 步操作,那么 101、102 和 103 三台机器的 seata 配置一摸一样。

顺次启动 3 台机器的 seata server

# 切换到 192.168.56.101 机器上操作
cd /home/appuser/opt/seata/seata-server-1.4.2/bin
./seata-server.sh -h 192.168.56.101 -p 8091 -n 1

# 切换到 192.168.56.102 机器上操作
cd /home/appuser/opt/seata/seata-server-1.4.2/bin
./seata-server.sh -h 192.168.56.102 -p 8091 -n 2

# 切换到 192.168.56.103 机器上操作
cd /home/appuser/opt/seata/seata-server-1.4.2/bin
./seata-server.sh -h 192.168.56.103 -p 8091 -n 3

2、查看 seata server 列表

5、在虚拟机上放行 8091 端口

# 防火墙放行 8091 端口
firewall-cmd --zone=public --add-port=8091/tcp --permanent
# 从新加载防火墙配置
firewall-cmd --reload

四、属性配置

1、外围关注的属性

服务端配置端 解释 客户端配置 解释
registry.type 注册核心类型 registry.type 注册核心类型
config.type 配置核心类型 config.type 配置核心类型
#store.mode=db须要以下配置 service.vgroupMapping.my_test_tx_group 事物分组,对应的值是 集群
store.db.driverClassName 驱动类 service.default.grouplist TC 服务列表 仅注册核心为 file 时应用
store.db.url 数据库连贯 url service.disableGlobalTransaction 是否开启全局事务
store.db.user 数据库用户名 client.rm.lock.retryInterval 校验或占用全局锁重试距离 默认 10,单位毫秒
store.db.password 数据库明码 client.rm.lock.retryTimes 校验或占用全局锁重试次数 默认 30
#store.mode=redis 须要以下配置
store.redis.host redis 地址
store.redis.port redis 端口
store.redis.database redis 数据库,默认是 0
store.redis.password redis 明码,没有不填写

2、服务端配置

1、undo 日志保留天数

# undo 保留天数,默认是 7 天
server.undo.logSaveDays=7

2、事务会话信息存储形式

# 事务会话信息存储形式,file 本地文件(不反对 HA),db 数据库 |redis(反对 HA)
store.mode
    =file
        须要配置的属性
            store.file.dir(file 模式文件存储文件夹名, 默认 sessionStore)
  =db
      须要配置的属性
          store.db.datasource(db 模式数据源类型    dbcp、druid、hikari;无默认值, 必须指定。)
          store.db.dbType(db 模式数据库类型    mysql、oracle、db2、sqlserver、sybaee、h2、sqlite、access、postgresql、oceanbase;无默认值,必须指定。)
          store.db.driverClassName(db 模式数据库驱动, 必须指定)
          store.db.url(db 模式数据库 url, 必须指定,在应用 mysql 作为数据源时,倡议在连贯参数中加上 rewriteBatchedStatements=true)
          store.db.user(db 模式数据库账户, 必须指定)
          store.db.password(db 模式数据库账户明码, 必须指定)    
          store.db.minConn    db 模式数据库初始连接数    默认 1
      store.db.maxConn    db 模式数据库最大连接数    默认 20
      store.db.maxWait    db 模式获取连贯时最大等待时间    默认 5000,单位毫秒
      store.db.globalTable    db 模式全局事务表名    默认 global_table
      store.db.branchTable    db 模式分支事务表名    默认 branch_table
      store.db.lockTable    db 模式全局锁表名    默认 lock_table
      store.db.queryLimit    db 模式查问全局事务一次的最大条数    默认 100
  =redis
      须要配置的属性
          store.redis.host    redis 模式 ip    默认 127.0.0.1
      store.redis.port    redis 模式端口    默认 6379
      store.redis.maxConn    redis 模式最大连接数    默认 10
      store.redis.minConn    redis 模式最小连接数    默认 1
      store.redis.database    redis 模式默认库    默认 0
      store.redis.password    redis 模式明码(无可不填)    默认 null
      store.redis.queryLimit    redis 模式一次查问最大条数    默认 100
            

3、度量配置

metrics.enabled    是否启用 Metrics    默认 false 敞开,在 False 状态下,所有与 Metrics 相干的组件将不会被初始化,使得性能损耗最低
metrics.registryType    指标注册器类型    Metrics 应用的指标注册器类型,默认为内置的 compact(繁难)实现,这个实现中的 Meter 仅应用无限内存计数,性能高足够满足大多数场景;目前只能设置一个指标注册器实现
metrics.exporterList    指标后果 Measurement 数据输入器列表    默认 prometheus,多个输入器应用英文逗号宰割,例如 "prometheus,jmx",目前仅实现了对接 prometheus 的输入器
metrics.exporterPrometheusPort    prometheus 输入器 Client 端口号    默认 9898

3、客户端配置

1、数据源代理

seata.enabled    是否开启 spring-boot 主动拆卸    true、false,(SSBS)专有配置,默认 true
seata.enableAutoDataSourceProxy=true    是否开启数据源主动代理    true、false,seata-spring-boot-starter(SSBS)专有配置,SSBS 默认会开启数据源主动代理, 可通过该配置项敞开.
seata.useJdkProxy=false    是否应用 JDK 代理作为数据源主动代理的实现形式    true、false,(SSBS)专有配置, 默认 false, 采纳 CGLIB 作为数据源主动代理的实现形式

2、事物分组的配置

service.vgroupMapping.my_test_tx_group    事务群组    my_test_tx_group 为分组,配置项值为 TC 集群名
service.default.grouplist    TC 服务列表    仅注册核心为 file 时应用

3、分布式事务降级开关

client.tm.degradeCheck    降级开关    默认 false。业务侧依据间断谬误数主动降级不走 seata 事务

4、校验或占用全局锁重试

client.rm.lock.retryInterval    校验或占用全局锁重试距离    默认 10,单位毫秒
client.rm.lock.retryTimes    校验或占用全局锁重试次数    默认 30

5、一阶段全局后果上报次数

client.tm.commitRetryCount    一阶段全局提交后果上报 TC 重试次数    默认 1 次,倡议大于 1
client.tm.rollbackRetryCount    一阶段全局回滚后果上报 TC 重试次数    默认 1 次,倡议大于 1 

五、参考文档

1、seata server 下载

2、Seata 老手部署指南(1.4.0 版本)

3、Seata 高可用部署

4、seata 配置属性

退出移动版