微服务保护和分布式事务(4)

米饭3个月前行业资讯113

二、分布式事务

首先我们看看项目中的下单业务整体流程(主要理解思路):

image-20241121193532500

由于订单、购物车、商品分别在三个不同的微服务,而每个微服务都有自己独立的数据库,因此下单过程中就会跨多个数据库完成业务。而每个微服务都会执行自己的本地事务:


交易服务:下单事务。

购物车服务:清理购物车事务。

库存服务:扣减库存事务。

整个业务中,各个本地事务是有关联的。因此每个微服务的本地事务,也可以称为分支事务。多个有关联的分支事务一起就组成了全局事务。我们必须保证整个全局事务同时成功或失败。


我们知道每一个分支事务就是传统的单体事务,都可以满足 ACID 特性,但全局事务跨越多个服务、多个数据库,不遵守 ACID 原则,归其原因就是参与事务的多个子业务在不同的微服务,跨越了不同的数据库。虽然每个单独的业务都能在本地遵循ACID,但是它们互相之间没有感知,不知道有人失败了,无法保证最终结果的统一,也就无法遵循ACID的事务特性了。


这就是分布式事务问题,出现以下情况之一就可能产生分布式事务问题:


业务跨多个服务实现

业务跨多个数据源实现

下面我们来学习一下如何解决分布式事务。


2.1 认识 Seata:

解决分布式事务的方案有很多,但实现起来都比较复杂,因此我们一般会使用开源的框架来解决分布式事务问题。在众多的开源分布式事务框架中,功能最完善、使用最多的就是阿里巴巴在 2019 年开源的 Seata 了。


其实分布式事务产生的一个重要原因,就是参与事务的多个分支事务互相无感知,不知道彼此的执行状态。因此解决分布式事务的思想非常简单:


就是找一个统一的事务协调者,与多个分支事务通信,检测每个分支事务的执行状态,保证全局事务下的每一个分支事务同时成功或失败即可。大多数的分布式事务框架都是基于这个理论来实现的。


Seata也不例外,在Seata的事务管理中有三个重要的角色:


TC **(Transaction Coordinator) -事务协调者:**维护全局和分支事务的状态,协调全局事务提交或回滚。

TM (Transaction Manager) - **事务管理器:**定义全局事务的范围、开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - **资源管理器:**管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

Seata 的工作架构如图所示:

image-20241121194609919

其中,TM和RM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TM和RM就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。


而TC服务则是事务协调中心,是一个独立的微服务,需要单独部署。


部署 TC 服务:


由于博客不好携带文件,所以如何部署 TC 服务,就需要友友自己去网上找找了。


2.2 微服务集成 Seata:

参与分布式事务的每一个微服务都需要集成 Seata,我们以trade-service为例。


2.2.1 引入依赖:

 <!--seata-->
  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
  </dependency>

2.2.2 配置:

seata:
  registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
    type: nacos # 注册中心类型 nacos
    nacos:
      server-addr: 192.168.242.128:8848 # nacos地址
      namespace: "" # namespace,默认为空
      group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUP
      application: seata-server # seata服务名称
      username: nacos
      password: nacos
  tx-service-group: hmall # 事务组名称
  service:
    vgroup-mapping: # 事务组与tc集群的映射关系
      hmall: "default"
  data-source-proxy-mode: AT # 选择分布式事务模式

2.2.3 添加数据库表:

这里需要在原来的数据库添加一张表:

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';


本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!  

云掣基于多年在运维领域的丰富时间经验,编写了《云运维服务白皮书》,欢迎大家互相交流学习:

《云运维服务白皮书》下载地址:https://fs80.cn/v2kbbq

想了解更多大数据运维托管服务、数据库运维托管服务、应用系统运维托管服务的的客户,欢迎点击云掣官网沟通咨询:https://yunche.pro/?t=shequ


相关文章

一文帮你理解整个SRE运维体系

一文帮你理解整个SRE运维体系

SRE运维体系的构建和工作职责划分。SRE工程师近年来的岗位需求逐年增加,被称为IT行业十大最受欢迎的行业之一。可观测性系统在任何有一定规模的企业内部,一旦推行起来整个SRE的运维模式,那么对于可观测...

JAVA 程序员-云计算学习路径

JAVA 程序员-云计算学习路径

课程内容关系图第一章:容器化基础云计算简单概念测试安装 Nginx服务器的安全组设置按量付费优点私有网络 VPC 实战Docker 基础概念开通华为服务器Docker 安装镜像操作容器操作修改容器内容...

Linux CentOS7虚拟机配置静态IP并允许上网的配置方法

Linux CentOS7虚拟机配置静态IP并允许上网的配置方法

前言当我们成功的将CentOS镜像安装到了我们的虚拟机上后,可是这个时候,虚拟机还没有配置IP信息,为了后面开发方便,我们需要设置一个静态IP。一、开启本地电脑VMnet8本地电脑,右键点击网络-&g...

Docker:namespace隔离实战

Docker:namespace隔离实战

namespacenamespace通过一种内核技术来实现,允许将不同的系统资源隔离和封装到独立的命名空间中。为容器化、虚拟化和隔离提供强大的基础。通过使用namespace技术,Linux内核可以创...

Spring AMQP与RabbitMQ深度整合指南:从基础到高级应用(3)

Spring AMQP与RabbitMQ深度整合指南:从基础到高级应用(3)

3.5 声明交换机和队列:在之前我们都是基于RabbitMQ控制台来创建队列、交换机。但是在实际开发时,队列和交换机是程序员定义的,将来项目上线,又要交给运维去创建。那么程序员就需要把程序中运行的所有...

【Docker 】深入探索 Docker :高阶操作与配置设置(上)

【Docker 】深入探索 Docker :高阶操作与配置设置(上)

Docker 是现代应用开发和部署的重要工具,能够帮助开发者轻松创建、管理和部署容器化应用。除了基本的命令外,掌握高阶操作和配置设置将大大提高您的工作效率和应用性能。本文将介绍一些 Docker 的高...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。