【微服务33】分布式事务Seata源码解析一:在IDEA中启动Seata Server

简介: 【微服务33】分布式事务Seata源码解析一:在IDEA中启动Seata Server

一、前言

至此,博主介绍了一些Seata环境搭建的常见坑、Seata的两种案例(SpringCloud集成Seata、SpringCloud集成Nacos + Seata):

  1. can not get cluster name in registry config ‘service.vgroupMapping.xx‘, please make sure registry问题解决
  2. Seata Failed to get available servers: endpoint format should like ip:port 报错原因/解决方案汇总版(看完本文必解决问题)
  3. Seata json decode exception, Cannot construct instance of java.time.LocalDateTime报错原因/解决方案最全汇总版
  4. 【微服务 31】超细的Spring Cloud 整合Seata实现分布式事务(排坑版)
  5. 【微服务 32】Spring Cloud整合Seata、Nacos实现分布式事务案例(巨细排坑版)【云原生】

从本文开始,进入到seata源码解析系列文章;前面几篇将即AT模式为例解析Seata-Server 和 Seata-Client的交互运作流程;

在真正开始解析源码之前,我们先在IDEA中把Seata Server跑起来;

PS:前文中搭建的Seata案例,seata的版本为1.3.0,而本文开始的源码分析将基于当前(2022年8月)最新的版本1.5.2进行源码解析。

读者请根据: 【微服务 31】超细的Spring Cloud 整合Seata实现分布式事务(排坑版) 一文自行调整SpringBoot、SpringCloud、Spring Cloud Alibaba、Seata的版本(参考博文:SpringBoot、SpringCloud、SpringCloudAlibaba的版本对应关系),具体使用的版本见下一篇文章。

二、IDEA中运行Seata Server

先问自己个问题:为什么要在本地运行seata server?就博文个人感觉:seata server里面的类嵌套特别深,有时会感觉没那么必要;有一些细节点需要通过debug的方式验证推测;实践出真知!!!

本着最小依赖、验证核心功能的初衷,本文Seata Server的本地运行基于File的配置/注册方式、DB的存储数据方式;

1、把源码从Github中荡下来

源码GitHub地址:https://github.com/seata/seata/tree/v1.5.2

在这里插入图片描述

通过New Project from Version Control...的方式将源码项目拉倒本地;

在这里插入图片描述

选择Git代码分支:origin/1.5.2,整体项目结构如下:

在这里插入图片描述

Seata Server使用到的DB

进入当前源码项目的如下目录:

在这里插入图片描述

在本地MySQL数据库新建数据库seata_server,然后在其中运行mysql.sql文件,生成的表结构如下:

在这里插入图片描述

表的作用如下:

  • branch_table用于保存分支事务数据
  • global_table用于保存全局事务数据
  • lock_table用于保存全局锁数据
  • distributed_lock用于保存分布式锁数据

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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = InnoDB
  DEFAULT 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 = 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、调整seata-server的配置

下载并运行seata-server时,如果采用file的方式,我们需要在registry.conf中配置seata-server的服务注册信息、file.conf中配置seata-server的服务配置信息;

按照这个思路,以file.conf为例全局搜索(command + shift + o):file.conf;

在这里插入图片描述

可以看到查出了很多file.conf文件,但是很多都是在test目录下,肯定不是我们想要的;非test目录有两个file.conf文件,文件目录分别为:script/client/confconfig/seata-config/core/src/main/resources;又因为script/目录是一个使用seata-server时需要的一些信息目录,所以锁定config/seata-config/core/src/main/resources目录,然后对其做出必要修改,包括seata-server的数据存储方式采用DB。registy.conf同样操作;

运行项目后发现,配置并没有生效,因为seata-server的数据存储方式依旧采用默认的file:
在这里插入图片描述

seata-server

进入到seata-server目录,可以发现这是一个SpringBoot项目,其中包括了一个application.example.yml文件;

在这里插入图片描述

application.example.yml文件中部分内容如下:

在这里插入图片描述

这个不就是在file.conf中配置的seata-server的数据存储方式吗!我们大胆推测IDEA中本地运行seata-server时,配置信息需要写在application.yml文件中;示例内容如下:

server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata

console:
  user:
    username: seata
    password: seata

seata:
  server:
    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
    max-commit-retry-timeout: -1
    max-rollback-retry-timeout: -1
    rollback-retry-timeout-unlock-enable: false
    enable-check-auth: true
    enable-parallel-request-handle: true
    retry-dead-threshold: 130000
    xaer-nota-retry-timeout: 60000
    recovery:
      handle-all-session-period: 1000
    undo:
      log-save-days: 7
      log-delete-period: 86400000
    session:
      branch-async-queue-size: 5000 #branch async remove queue size
      enable-branch-async-remove: false #enable to asynchronous remove branchSession
  config:
    # support: nacos 、 consul 、 apollo 、 zk  、 etcd3
    type: file
  registry:
    type: file
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

  store:
    # support: file 、 db 、 redis
    mode: db
    session:
      mode: db
    lock:
      mode: db
    file:
      dir: sessionStore
      max-branch-session-size: 16384
      max-global-session-size: 512
      file-write-buffer-cache-size: 16384
      session-reload-read-size: 100
      flush-disk-mode: async
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata_server?rewriteBatchedStatements=true
      user: root
      password: 123456
      min-conn: 5
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 100
      max-wait: 5000
    redis:
      mode: single
      database: 0
      min-conn: 1
      max-conn: 10
      password:
      max-total: 100
      query-limit: 100
      single:
        host: 127.0.0.1
        port: 6379
      sentinel:
        master-name:
        sentinel-hosts:
  metrics:
    enabled: false
    registry-type: compact
    exporter-list: prometheus
    exporter-prometheus-port: 9898
  transport:
    rpc-tc-request-timeout: 30000
    enable-tc-server-batch-send-response: false
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      boss-thread-size: 1

这里有一点比较有意思:

  • 如果我们没有配置seata-server通信(netty)的端口号,则默认为${server.port} + 1000,当然如果我们不配置,由于server.port默认是7091,所以seata-server通信(netty)的端口号默认为8091。

3、运行seata-server

seata-server项目是一个正常的SpringBoot项目,就直接按照运行SpringBoot的方式运行其即可;

在这里插入图片描述

Server类中打个端点,验证我们对seata-server的配置是否生效;

在这里插入图片描述

运行结果如我们预期,seata-server的数据模式修改为了db;

三、总结和后续

IDEA中运行seata-server等价于是在本地运行一个SringBoot项目,进需把需要的配置配置在application.yml文件中即可;

后续正式开始seata的源码解析。

相关文章
|
6月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
138 0
|
7月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1141 3
|
5月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
11月前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
384 5
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
1022 1
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
存储 运维 数据可视化
如何为微服务实现分布式日志记录
如何为微服务实现分布式日志记录
894 1
|
消息中间件 存储 负载均衡
微服务与分布式系统设计看这篇就够了!
【10月更文挑战第12天】 在现代软件架构中,微服务和分布式系统设计已经成为构建可扩展、灵活和可靠应用程序的主流方法。本文将深入探讨微服务架构的核心概念、设计原则和挑战,并提供一些关于如何在分布式系统中实现微服务的实用指导。
581 2
|
网络协议 定位技术 Windows
Windows Server 2019 DNS服务器搭建
Windows Server 2019 DNS服务器搭建
721 1
|
10月前
|
Java 应用服务中间件 Maven
在IntelliJ IDEA中如何配置使用Maven以创建Tomcat环境
所以,别担心这些工具看起来有些吓人,实际上这些都是为了帮助你更好的完成工作的工具,就像超市里的各种烹饪工具一样,尽管它们看起来可能很复杂,但只要你学会用,它们会为你烹饪出一道道美妙的食物。这就是学习新技能的乐趣,让我们一起享受这个过程,攀登知识的高峰!
666 27

推荐镜像

更多
  • DNS