微服务之分布式事务篇 Seata入门

微服务之分布式事务篇 Seata

Seata简介

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata基础概念

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

Seata使用场景

  1. 实例场景:购买商品下单逻辑
    • 仓储服务:对给定的商品扣除仓储数量
    • 订单服务:根据采购需求创建订单
    • 帐户服务:从用户帐户中扣除余额
  2. 架构图

    在这里插入图片描述
  3. Seata的分布式交易解决方案

    在这里插入图片描述

Seata入门案例配置中心为nacos

  1. 下载seata-server

  2. 以RuoYi微服务为基础框架(也可自行搭建服务框架)

    1. 下载地址:https://gitee.com/y_project/RuoYi-Cloud.git
    2. 文档启动项目文档:http://doc.ruoyi.vip/ruoyi-cloud/
  3. 解压seata-server, 并修改其中的conf/registry.conf文件, 不指定的话registry.conf就是seata的主配置文件

    registry {
      type = "nacos"
      nacos {
        application = "seata-server"
        serverAddr = "127.0.0.1:8848"
        group = "SEATA_GROUP"
        namespace = ""
        cluster = "my_test_cluster"	# 默认集群名称为default, 此处自定义了
        username = ""
        password = ""
      }
    }
    config {
      type = "nacos"
      nacos {
        serverAddr = "127.0.0.1:8848"
        namespace = ""
        group = "SEATA_GROUP"
        username = ""
        password = ""
        dataId = "seataServer.properties"
      }
    }
    
  4. 启动在bin下的seata-server.sh,这时就可以在nacos的服务列表中看到seata-server
    在这里插入图片描述

  5. 由于seata使用mysql作为db高可用数据库,故需要在mysql创建一个ry-seata库,并导入数据库脚本。

    DROP TABLE IF EXISTS `global_table`;
    CREATE TABLE `global_table`  (
      `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `transaction_id` bigint(20) NULL DEFAULT NULL,
      `status` tinyint(4) NOT NULL,
      `application_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `transaction_service_group` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `transaction_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `timeout` int(11) NULL DEFAULT NULL,
      `begin_time` bigint(20) NULL DEFAULT NULL,
      `application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `gmt_create` datetime NULL DEFAULT NULL,
      `gmt_modified` datetime NULL DEFAULT NULL,
      PRIMARY KEY (`xid`) USING BTREE,
      INDEX `idx_gmt_modified_status`(`gmt_modified`, `status`) USING BTREE,
      INDEX `idx_transaction_id`(`transaction_id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '全局事务表' ROW_FORMAT = Dynamic;
    
    DROP TABLE IF EXISTS `branch_table`;
    CREATE TABLE `branch_table`  (
      `branch_id` bigint(20) NOT NULL,
      `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `transaction_id` bigint(20) NULL DEFAULT NULL,
      `resource_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `branch_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `status` tinyint(4) NULL DEFAULT NULL,
      `client_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `application_data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `gmt_create` datetime(6) NULL DEFAULT NULL,
      `gmt_modified` datetime(6) NULL DEFAULT NULL,
      PRIMARY KEY (`branch_id`) USING BTREE,
      INDEX `idx_xid`(`xid`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '分支事务表' ROW_FORMAT = Dynamic;
    
    DROP TABLE IF EXISTS `lock_table`;
    CREATE TABLE `lock_table`  (
      `row_key` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
      `xid` varchar(96) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `transaction_id` bigint(20) NULL DEFAULT NULL,
      `branch_id` bigint(20) NOT NULL,
      `resource_id` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `table_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `pk` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
      `gmt_create` datetime NULL DEFAULT NULL,
      `gmt_modified` datetime NULL DEFAULT NULL,
      PRIMARY KEY (`row_key`) USING BTREE,
      INDEX `idx_branch_id`(`branch_id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '全局锁数据' ROW_FORMAT = Dynamic;
    
  6. 在seata解压的目录下查看config.txt(没有则创建)
    在这里插入图片描述

    client.undo.logSerialization=kryo # 不添加这个配置会报序列化有关的错
    service.vgroupMapping.ruoyi-students-group=my_test_cluster # 另一个微服务
    service.vgroupMapping.ruoyi-system-group=my_test_cluster # 一个微服务
    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/ry-seata?useUnicode=true
    store.db.user=root
    store.db.password=password
    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
    
  7. 在conf文件夹下查看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
    
    urlencode() {
      for ((i=0; i < ${#1}; i++))
      do
        char="${1:$i:1}"
        case $char in
        [a-zA-Z0-9.~_-]) printf $char ;;
        *) printf '%%%02X' "'$char" ;;
        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=$(urlencode $1)&group=$group&content=$(urlencode $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
    
  8. 使配置生效: sh nacos-config.sh 127.0.0.1 # nacos地址

  9. 新增或修改服务在nacos上的配置文件

    # spring配置
    spring: 
      datasource:
        dynamic:
          # 开启seata代理
          seata: true
    	  
    # seata配置
    seata:
      enabled: true
      # Seata 应用编号,默认为 ${spring.application.name}
      application-id: ${spring.application.name}
      # Seata 事务组编号,用于 TC 集群名
      tx-service-group: ${spring.application.name}-group
      # 关闭自动代理
      enable-auto-data-source-proxy: false
      # 服务配置项
      service:
        # 虚拟组和分组的映射
        vgroup-mapping:
          ruoyi-system-group: my_test_cluster # 注意这里配置的是集群名称
      config:
        type: nacos
        nacos:
          serverAddr: 127.0.0.1:8848
          group: SEATA_GROUP
          namespace:
      registry:
        type: nacos
        nacos:
          application: seata-server
          server-addr: 127.0.0.1:8848
          namespace:
    

总结

  1. 源码已上传码云
  2. 另外有一篇Seata源码解读,一并奉上
  3. 相关文章列表
    1. 微服务之网关篇 Spring Cloud Gateway
    2. 微服务之注册中心篇 Nacos
    3. 微服务之配置中心篇 Naocs
    4. 微服务之远程调用篇 OpenFeign
    5. 微服务之服务监控篇 Actuator&Admin
    6. 微服务之链路追踪篇 Skywalking
    7. 微服务之分布式日志 ELK
    8. 微服务思想介绍
    9. 微服务之熔断与降级篇 Sentinel
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、课程简介Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。       在本套课程中,我们将全面的讲解Spring Cloud技术栈, 从环境的部署到技术的应用,再到项目实战,让我们不仅是学习框架技术的使用,而且可以学习到使用Spring Cloud如何解决实际的问题。Spring Cloud各个组件相互配合,合作支持了一套完整的微服务架构。- 注册中心负责服务的注册与发现,很好将各服务连接起来- 断路器负责监控服务之间的调用情况,连续多次失败进行熔断保护。- API网关负责转发所有对外的请求和服务- 配置中心提供了统一的配置信息管理服务,可以实时的通知各个服务获取最新的配置信息- 链路追踪技术可以将所有的请求数据记录下来,方便我们进行后续分析- 各个组件又提供了功能完善的dashboard监控平台,可以方便的监控各组件的运行状况2、适应人群有一定的Java基础,并且要有一定的web开发基础。3、课程亮点       系统的学习Spring Cloud技术栈,由浅入深的讲解微服务技术。涵盖了基础知识,原理剖析,组件使用,源码分析,优劣分析,替换方案等,以案例的形式讲解微服务中的种种问题和解决方案l  微服务的基础知识n  软件架构的发展史n  微服务的核心知识(CAP,RPC等)l  注册中心n  Eureka搭建配置服务注册n  Eureka服务端高可用集群n  Eureka的原理和源码导读n  Eureka替换方案Consuln  Consul下载安装&服务注册&高可用l  服务发现与服务调用n  Ribbon负载均衡基本使用&源码分析n  Feign的使用与源码分析n  Hystrix熔断(雪崩效应,Hystrix使用与原理分析)n  Hystrix替换方案Sentinell  微服务网关n  Zuul网关使用&原理分析&源码分析n  Zuul 1.x 版本的不足与替换方案n  SpringCloud Gateway深入剖析l  链路追踪n  链路追踪的基础知识n  Sleuth的介绍与使用n  Sleuth与Zipkin的整合开发l  配置中心n  SpringClond Config与bus 开发配置中心n  开源配置中心Apollo4、主讲内容章节一:1.     微服务基础知识2.     SpringCloud概述3.     服务注册中心Eureka4.     Eureka的替换方案Consul章节二:1.     Ribbon实现客户端负载均衡2.     基于Feign的微服务调用3.     微服务熔断技术Hystrix4.     Hystrix的替换方案Sentinel章节三:1.     微服务网关Zuul的基本使用2.     Zuul1.x 版本的不足和替换方案3.     深入SpringCloud Gateway4.     链路追踪Sleuth与Zipkin章节四:1.     SpringCloud Config的使用2.     SpringCloud Config结合SpringCloud Bus完成动态配置更新3.     开源配置中心Apollo

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值