当前位置: 首页 > news >正文

分布式事务学习笔记(二)Seata架构、TC服务器部署、微服务集成Seata

文章目录

  • 前言
  • 2 Seata
    • 2.1 Seata的架构
    • 2.2 部署TC服务
      • 1)下载安装包
      • 2)解压
      • 3)修改配置文件
      • 4)在Nacos中添加TC服务配置
      • 5)创建数据库表
      • 6)启动TC服务
      • 7)查看TC服务
    • 2.3 微服务集成Seata
      • 2.3.1 引入依赖
      • 2.3.2 配置TC服务地址
      • 2.3.3 配置其他微服务
      • 2.3.3 启动微服务

前言

分布式事务学习笔记(一)分布式事务问题、CAP定理、BASE理论、Seata

2 Seata

Seata是2019年1月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

官网地址:http://seata.io/

2.1 Seata的架构

Seata在分布式事务管理中有三个重要的角色:

  • TC (Transaction Coordinator):事务协调者,维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager):事务管理器,定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager):资源管理器,管理分支事务处理的资源,注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

Seata基于上述架构提供了四种不同的分布式事务解决方案:

  • AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式
  • XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入;
  • TCC模式:最终一致的分阶段事务模式,有业务侵入;
  • SAGA模式:长事务模式,有业务侵入;

2.2 部署TC服务

1)下载安装包

点击官网顶部的“下载”按钮进入下载页,下载最新版本的安装包:

2)解压

3)修改配置文件

修改conf目录下的application.yml文件:

server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${log.home:${user.home}/logs/seata}console:user:username: seatapassword: seataseata:registry:# TC服务的注册中心,支持: nacos, eureka, redis, zk, consul, etcd3, sofatype: nacosnacos:# 注册到nacos的名称application: seata-tc-serviceserver-addr: 127.0.0.1:8848group: DEFAULT_GROUPnamespace:username:password:cluster: defaultconfig:# 读取TC服务端的配置文件的方式,支持: nacos, consul, apollo, zk, etcd3type: nacosnacos:server-addr: 127.0.0.1:8848namespace:group: DEFAULT_GROUPusername:password:# TC服务端配置文件data-id: seataServer.propertiesstore:mode: filesecurity:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.jpeg,/**/*.ico,/api/v1/auth/login,/version.json,/health,/error

4)在Nacos中添加TC服务配置

为了让TC服务集群可以共享配置,选择Nacos作为统一配置中心。因此TC服务端配置文件seataServer.properties文件需要在nacos中配好:

配置内容如下:

# 数据存储方式,db代表数据库
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
#改成自己的数据库和账密
store.db.url=jdbc:mysql://127.0.0.1:3306/jingd?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=1*****
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
# 事务、日志等配置
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.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none
# 关闭metrics功能,提高性能
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

5)创建数据库表

TC服务在管理分布式事务时,需要记录记全局事务、分支事务、全局锁等相关数据到数据库中,因此需要提前创建好相关表。

根据Seata官方文档,需要新建global_table表、branch_table表、lock_table表、distributed_lock表。具体的SQL在:https://gitee.com/seata-io/seata/blob/v1.5.1/script/server/db/mysql.sql

-- -------------------------------- 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_status_gmt_modified` (`status` , `gmt_modified`),KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;-- 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 = InnoDBDEFAULT CHARSET = utf8mb4;-- 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),`status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',`gmt_create`     DATETIME,`gmt_modified`   DATETIME,PRIMARY KEY (`row_key`),KEY `idx_status` (`status`),KEY `idx_branch_id` (`branch_id`),KEY `idx_xid_and_branch_id` (`xid` , `branch_id`)
) ENGINE = InnoDBDEFAULT CHARSET = utf8mb4;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 = InnoDBDEFAULT 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);

6)启动TC服务

进入bin目录,运行seata-server.bat脚本:

报错提示找不到MySQL驱动,让加一个驱动jar到lib目录下:

Caused by: org.apache.seata.common.exception.StoreException: the {com.mysql.jdbc.Driver} can’t be found in the path E:\Program Files\apache-seata-2.1.0-incubating-bin/lib/jdbc/, please copy database driver dependencies, such as mysql-connector-java.jar to the path.

再次启动成功:

7)查看TC服务

在Nacos控制台可以看到TC服务已注册:

在浏览器访问http://127.0.0.1:7091,输入账密进入TC服务控制台:

2.3 微服务集成Seata

jd-order-service微服务为例:

2.3.1 引入依赖

<!--seata-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><exclusions><!--版本较低,1.3.0,因此排除--> <exclusion><artifactId>seata-spring-boot-starter</artifactId><groupId>io.seata</groupId></exclusion></exclusions>
</dependency>
<dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><!--seata starter 采用1.4.2版本--><version>${seata.version}</version>
</dependency>

2.3.2 配置TC服务地址

jd-order-service微服务中的application.yml中,配置TC服务地址,通过注册中心Nacos,结合服务名称获取TC地址:

seata:registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取TC服务地址type: nacos # 注册中心类型 Nacosnacos:server-addr: 127.0.0.1:8848namespace: ""group: DEFAULT_GROUPapplication: seata-tc-server # Seata服务名称username:password:tx-service-group: default_tx_group # 事务组名称service:vgroup-mapping: # 事务组与cluster的映射关系default_tx_group: default

特别要注意的是,这里的配置和TC服务器的配置要对应起来:

2.3.3 配置其他微服务

jd-order-service微服务和jd-order-service微服务做相同配置。

2.3.3 启动微服务

服务启动后,通过日志可以看到TC服务成功注册到Nacos,且TM、RM注册成功:

至此,微服务整合Seata完毕,接下来就可以使用Seata来管理分布式事务了。

本节完,更多内容请查阅分类专栏:微服务学习笔记

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析
  • MyBatis3源码深度解析
  • Redis从入门到精通
  • MyBatisPlus详解
  • SpringCloud学习笔记

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 若依VUE项目安全kind-of postcss vite漏洞扫描和修复
  • 常见面试题之计算机网络
  • Linux内核结构
  • “msvcr120.dll丢失”的错误提示应该如何修复?几种修复方法详细介绍
  • 【有啥问啥】深入解析:机器学习中的过拟合与欠拟合
  • cadence SPB17.4 - allegro - 用板子外形创建整板铺铜
  • Android IME输入法启动显示隐藏流程梳理
  • 有效安全计划评估的基本指标
  • 茴香豆:企业级知识问答工具实践闯关任务
  • Win10 录屏秘籍大公开:从新手到高手的进阶之路
  • Golang | Leetcode Golang题解之第419题棋盘上的战舰
  • JAVA虚拟机----JVM
  • VMware安装飞牛私有云fnOS并挂载小雅Alist实现异地远程访问
  • 【LInux】HTTPS是如何实现安全传输的
  • 设计模式--责任链模式
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 0基础学习移动端适配
  • Angular Elements 及其运作原理
  • CentOS从零开始部署Nodejs项目
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • C语言笔记(第一章:C语言编程)
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Java|序列化异常StreamCorruptedException的解决方法
  • java8 Stream Pipelines 浅析
  • JavaScript设计模式系列一:工厂模式
  • Netty源码解析1-Buffer
  • React-生命周期杂记
  • vue的全局变量和全局拦截请求器
  • 回流、重绘及其优化
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 一个完整Java Web项目背后的密码
  • 阿里云服务器购买完整流程
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #微信小程序:微信小程序常见的配置传旨
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Oracle)SQL优化基础(三):看懂执行计划顺序
  • (pojstep1.1.2)2654(直叙式模拟)
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (九)c52学习之旅-定时器
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (一)插入排序
  • (游戏设计草稿) 《外卖员模拟器》 (3D 科幻 角色扮演 开放世界 AI VR)
  • (转载)从 Java 代码到 Java 堆
  • *** 2003
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET成年了,然后呢?
  • .NET上SQLite的连接
  • .Net下的签名与混淆
  • @Autowired @Resource @Qualifier的区别
  • @EnableWebSecurity 注解的用途及适用场景