Sentinel服务保护 + Seata分布式事务

服务保护

雪崩问题】微服务调用链路中某个服务,引起整个链路中所有微服务都不可用。在这里插入图片描述
原因】:

  1. 微服务相互调用,服务提供者出现故障。
  2. 服务调用这没有做好异常处理,导致自身故障。
  3. 调用链中所有服务级联失败,导致整个集群故障。

解决方案】:
请求限流、线程隔离、服务熔断
服务保护技术】:
在这里插入图片描述

Sentinel服务保护

官方文档:Sentinel

使用步骤

1. 使用docker部署sentinel

创建并运行sentinel容器:

docker run -d \
--net=host \
--name sentinel \
--restart=always \
-e AUTH_USERNAME=admin \
-e AUTH_PASSWORD=admin \
bladex/sentinel-dashboard:1.8.6

完成后在浏览器输入:192.168.140.101:8858,用户名admin,密码admin

2.在微服务中连接sentinel控制台

引入sentinel依赖:

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

配置控制台:

spring:cloud:sentinel:transport:dashboard: 192.168.140.101:8858 # sentinel的控制台地址http-method-specify: true # 开启请求方式前缀

Restful风格的API请求路径一般相同,会导致簇点资源名称重复。所以我们要修改配置,把请求方式 + 请求路径作为簇点资源名称

簇点链路

簇点链路就是单机调用链路,是一次请求进入服务后经过的每一个被Sentinel监控的资源链。默认Sentinel会监控SpringMVC的每一个Endpoint(Http接口)。限流、熔断等都是争对簇点链路中的资源设置的,资源名默认就是接口的请求路径。
在这里插入图片描述

解决方案

1. 请求限流

限制访问微服务的请求的并发量,避免服务因流量激增而出现故障。
在这里插入图片描述
在这里插入图片描述
这个接口每秒钟只能处理6个请求,使用ApiFox进行测试,会有部分请求失败【失败返回状态码429】。
在这里插入图片描述

2. 线程隔离

通过限定每个业务能使用的线程数量而将故障业务隔离,避免故障扩散。
在这里插入图片描述
场景】:假设有大量的查询购物车的请求,通过对查询购物车这个线程做线程隔离,可以保证购物车这个微服务的资源不会被耗尽,不会对修改购物车等其他业务造成影响。
在这里插入图片描述
在这里插入图片描述

线程隔离和请求限流的区别:
请求限流:控制接受请求的速度(每秒访问几次)
线程隔离:控制最多能接收请求的次数(一次访问的线程数)
就算请求限流设置的再慢,如果线程卡住的话,不设置线程隔离,也会导致资源占用。

3. fallback

在这里插入图片描述
一、 将FeignClient作为Sentinel的簇点资源:

feign:sentinel:enabled: true # 开启流量控制

二、 为FeignClient添加Fallback:

  • 方法1:FallbackClass,无法对远程调用的异常做处理
  • 方法2:FallbackFactory,可以对远程调用的异常做处理
  1. 自定义类,实现FallbackFactory,编写对某个FeignClient的fallback逻辑:
@Slf4j
public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {@Overridepublic ItemClient create(Throwable cause) {// 编写失败的处理逻辑(失败后就会走里边的方法)return new ItemClient() {@Overridepublic List<ItemDTO> queryItemByIds(Collection<Long> ids) {log.error("查询商品失败,"+ cause);return CollUtils.emptyList();}@Overridepublic void deductStock(List<OrderDetailDTO> items) {log.error("扣减商品库存失败,"+ cause);throw new RuntimeException(cause);}};}
}
  1. 将定义的FallbackFactory注册为一个Bean:
public class DefaultFeignConfig {@Beanpublic ItemClientFallbackFactory itemClientFallbackFactory() {return new ItemClientFallbackFactory();}
}
  1. 在ItemClient接口中使用FallbackFactory:@FeignClient(value = "item-service", fallbackFactory = ItemClientFallbackFactory.class)
@FeignClient(value = "item-service", fallbackFactory = ItemClientFallbackFactory.class)
public interface ItemClient {@GetMapping("/items")List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);@PutMapping("/items/stock/deduct")void deductStock(@RequestBody List<OrderDetailDTO> items);
}

在这里插入图片描述

4. 服务熔断

断路器统计请求的异常比例或慢调用比例,如果超出阈值则会熔断该业务,则拦截改接口的请求。熔断期间,所有请求快速失败,全部走fallback逻辑。当服务恢复时,断路器会放行访问该服务的请求。
在这里插入图片描述

断路器工作原理:

在这里插入图片描述
默认情况:Closed状态
如果失败的比例过高:就会进入Open状态【拦截一切请求,快速失败】
Open状态下会尝试放行一次请求,进入Half-Open状态,如果仍然失败,再次返回Open状态;如果成功,回到Closed状态

配置熔断策略

在这里插入图片描述
在这里插入图片描述

分布式事务

如果一个业务需要多个服务合作完成,而且每个服务都有事务,多个事务必须同时成功或同时失败,这样的事务就是分布式事务。其中每一个服务的事务就是一个分支事务。整个业务称为全局事务
场景】:用户下单后,订单服务首先创建订单,随后调用购物车服务清理购物车,最后调用库存服务扣减商品的库存。如果在调用库存服务的时候商品库存为0,此时扣减库存失败,订单服务和购物车服务应该同时失败。
在这里插入图片描述
出现问题的原因】:各个分支服务不知道对方的情况
解决思路】:让各个分支事务感受到对方的存在,让所有的微服务向事务协调者报告当前的状态。
在这里插入图片描述

Seata架构

  • 事务协调者(TC):维护全局和分支事务的状态,协调全局事务提交或回滚。
  • 事务管理器(TM):定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • 资源管理器(RM):管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态。
    在这里插入图片描述

1. 部署TC服务

  1. 创建数据库,导入sql文件
    在这里插入图片描述
CREATE DATABASE IF NOT EXISTS `seata`;
USE `seata`;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;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;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);
  1. 准备配置文件
    seata运行时所需的配置文件
    上传前先看看application.yml,里边可能有些配置需要改一下
    把上边的配置文件丢到root根目录下
    在这里插入图片描述
  2. docker部署
    在/root目录下执行以下命令,创建并允许seata容器
docker run --name seata \
-p 8099:8099 \
-p 7099:7099 \
-e SEATA_IP=192.168.140.101 \
-v ./seata:/seata-server/resources \
--privileged=true \
--network hm-net \
--restart=always \
-d \
seataio/seata-server:1.5.2
  1. 以上操作都完成后,在浏览器输入:http://192.168.140.101:7099/后即可登录seata控制台。(初始账号:admin、密码:admin)

2. 微服务集成Seata

  1. 引入Seata依赖
<!--seata-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
  1. 配置TC服务地址,让微服务找到TC服务地址
    在这里插入图片描述
seata:registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址type: nacos # 注册中心类型 nacosnacos:server-addr: 192.168.140.101:8848 # nacos地址namespace: "" # namespace,默认为空group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUPapplication: seata-server # seata服务名称username: nacospassword: nacostx-service-group: hmall # 事务组名称service:vgroup-mapping: # 事务组与tc集群的映射关系hmall: "default"

因为很多服务都需要实现分布式事务,所以可以把对于seata的配置抽取成一个共享配置写在nacos里。所以添加依赖的时候,检查一下是否有bootstrapnacos配置管理的依赖。

查看seata的日志文件,可以看到购物车服务、交易服务、商品服务已经全部和seata的TC服务建立连接。
在这里插入图片描述

3. Seata解决分布式事务问题

XA模式—强一致

在这里插入图片描述

  1. 一阶段工作:
  • RM注册分支事务
  • RM执行分支事务sql但不提交
  • RM报告执行状态到TC
  1. 二阶段工作:
  • TC检测各分支事务执行状态:
    • 如果都成功,通知所有RM提交事务
    • 如果有失败,通知所有RM回滚事务
  • RM接收到TC指令,提交或回滚事务

通过“等待”的方式,确保了全局事务的ACID特性。但是一阶段需要锁定数据库的资源,到二阶段才释放,性能差。

实现步骤
  1. 修改(每个参与事务的微服务)application.yml文件,开启XA模式
seata:data-source-proxy-mode: XA
  1. 给发起全局事务的入口添加@GlobalTransactional注解
    在这里插入图片描述

AT模式(主推)—最终一致

AT模式弥补了XA模式中资源锁定周期过长的缺陷。
在这里插入图片描述

  1. 一阶段RM的工作:
  • 注册分支事务
  • 记录undo-log(数据快照)
  • 执行业务sql并提交
  • 报告事务状态
  1. 二阶段提交时RM的工作:
  • 删除undo-log即可
  1. 二阶段回滚时RM的工作:
  • 根据undo-log恢复数据到更新前

AT模式相比于XA模式的优点在于:在一阶段不需要等待彼此执行,而是各自提交,这样资源就没有锁定,性能也会好。
但是如果二阶段需要进行回滚,在回滚之前,会出现数据短暂的不一致。
AT模式与XA模式的区别】:

  1. XA模式一阶段不提交事务,锁定资源
    AT模式一阶段直接提交,不锁定资源
  2. XA模式依赖数据库机制实现回滚
    AT模式利用数据快照实现回滚
  3. XA模式强一致
    AT模型最终一致
实现步骤
  1. 创建数据表,导入用来记录数据快照的undo_log表
    】:每个分支事务都需要有自己的undo_log表
-- 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 = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
  1. 修改application.yml文件,将事务模式修改为AT模式
seata:data-source-proxy-mode: AT

在这里插入图片描述
数据快照(undo_log表):
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/892339.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssh2-sftp-client uploadDir Upload error: getLocalStatus: Bad path: ./public

报错解释 这个错误表明在使用 ssh2-sftp-client 这个Node.js库进行目录上传时遇到了问题。具体来说&#xff0c;是指定的本地路径&#xff08;./public&#xff09;不正确或者不存在。 解决方法&#xff1a; 确认当前工作目录&#xff1a;确保你在执行上传操作时的当前工作目…

AI赋能服装零售:商品计划智能化,化危机为转机

在服装零售这片竞争激烈的战场上&#xff0c;每一个细微的决策都可能成为品牌兴衰的关键。当市场波动、消费者口味变化、供应链挑战接踵而至时&#xff0c;许多品牌往往将危机归咎于外部环境。然而&#xff0c;真相往往更为深刻——“危机不是外部的&#xff0c;而是你的商品计…

基于YOLOv8的水下目标检测系统

基于YOLOv8的水下目标检测系统 (价格90) 使用的是DUO水下目标检测数据集 训练集 6671张 验证集 1111张 测试集 1111张 包含 [holothurian, echinus, scallop, starfish] [海参, 海胆, 扇贝, 海星] 4个类 通过PYQT构建UI界面&#xff0c;包含图片检测&#xff0c;视…

【git】在服务器使用docker设置了一个gogs服务器,访问和现实都不理想

以下问题应该都可以通过设置custom/conf/app.ini来解决 配置文档参考地址:https://www.bookstack.cn/read/gogs_zh/advanced-configuration_cheat_sheet.md domain显示的事localhost&#xff0c;实际上应该是一个IP地址。 关键字&#xff1a; DOMAIN ROOT_URL 因为是docker…

统一门户单点登入(C#-OOS机制)

1.非自研系统 通过接口&#xff0c;获取第三方系统token&#xff0c;存redis缓存&#xff0c;设计跳转配置&#xff0c;根据获取的配置路由等用户信息来访问第三方系统免登录。&#xff08;登入校验在第三方系统实现&#xff09;/// <summary> /// 获取OA登录Token /// …

Julia语言的软件工程

Julia语言的软件工程探讨 引言 随着科技的迅猛发展&#xff0c;编程语言的发展也日新月异。在众多编程语言中&#xff0c;Julia作为一门新兴语言&#xff0c;以其高性能、易用性&#xff0c;以及强大的科学计算能力&#xff0c;逐渐吸引了大量开发者和研究人员的关注。本文旨…

web-前端小实验4

实现以上图片中的内容 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>用户注册</title&…

网站自动签到

我研究生生涯面临两个问题&#xff0c;一是写毕业论文&#xff0c;二是找工作&#xff0c;这两者又有很大的冲突。怎么解决这两个冲突呢&#xff1f;把python学好是一个路子&#xff0c;因此从今天我要开一个专栏就是学python 其实我的本意不是网站签到&#xff0c;我喜欢在起点…

【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法)

【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型&#xff08;敏感性分析方法&#xff09; 引言 该文章实现了一个可解释的神经网络回归模型&#xff0c;使用BP神经网络&#xff08;BPNN&#xff09;来预测特征输出。该模型利用七个变量参数作为输入特征进行训练。为…

F.interpolate函数

F.interpolate 是 PyTorch 中用于对张量&#xff08;通常是图像数据&#xff09;进行插值操作的函数&#xff0c;常用于调整张量的大小&#xff0c;例如改变图像的分辨率。它支持多种插值方法&#xff0c;包括最近邻插值、双线性插值和三次插值等。 语法 torch.nn.functional…

iOS 本地新项目上传git仓库,并使用sourceTree管理

此文记录的场景描述&#xff1a; iOS前期开发时&#xff0c;在本地创建项目&#xff0c;直至开发一段时间&#xff0c;初期编码及框架已完善后&#xff0c;才拿到git仓库的地址。此时需要将本地代码上传到git仓库。 上传至git仓库&#xff0c;可以使用终端&#xff0c;键入命令…

为深度学习引入张量

为深度学习引入张量 什么是张量&#xff1f; 神经网络中的输入、输出和转换都是使用张量表示的&#xff0c;因此&#xff0c;神经网络编程大量使用张量。 张量是神经网络使用的主要数据结构。 张量的概念是其他更具体概念的数学概括。让我们看看一些张量的具体实例。 张量…

欧拉公式和傅里叶变换

注&#xff1a;英文引文机翻&#xff0c;未校。 中文引文未整理去重&#xff0c;如有异常&#xff0c;请看原文。 Euler’s Formula and Fourier Transform Posted byczxttkl October 7, 2018 Euler’s formula states that e i x cos ⁡ x i sin ⁡ x e^{ix} \cos{x} i …

sql 函数

# 四则运算 - * / # 函数 distinct 、count、sum、max、min、avg、sum、round select concat(device_id 是,device_id ) device_id from device_id_apply_factor where device_id D6A42CE6A0; select concat_ws(|||,device_id ,factor_a ,module_type) from 、device_id_app…

边缘计算应用十大领域

边缘计算解决了互联网的网速问题&#xff0c;作为实现边缘计算的基础&#xff0c;那边缘计算是5G与产业互联网、物联网时代的重要技术支撑&#xff0c;也正迎来广阔的增长空间。那么现在我们生活中有哪些领域正在使用边缘计算呢&#xff1f;今天我们来盘点一下我们身边正在使用…

Python视频处理:噪声矩阵与并行计算的完美融合

噪声级别对视频质量有显著的影响&#xff0c;主要体现在以下几个方面&#xff1a; 1. 视觉质量 低噪声级别&#xff1a;当噪声级别较低时&#xff0c;视频的视觉质量较好。噪声对图像细节的干扰较小&#xff0c;画面看起来较为清晰和自然。观众可以更容易地识别图像中的细节和…

HDFS编程 - 使用HDFS Java API进行文件操作

文章目录 前言一、创建hdfs-demo项目1. 在idea上创建maven项目2. 导入hadoop相关依赖 二、常用 HDFS Java API1. 简介2. 获取文件系统实例3. 创建目录4. 创建文件4.1 创建文件并写入数据4.2 创建新空白文件 5. 查看文件内容6. 查看目录下的文件或目录信息6.1 查看指定目录下的文…

高德地图调用geoserver提供WMTS服务报错Unknown TILEMATRIX问题

1. 高德地图JSAPI要求WMTS必须是EPSG:3857坐标系 2. 高德调用WMTS服务时参数 TileMatrix中未带有坐标系字段&#xff0c;需要修改geoserver源码兼容一下&#xff0c;修改JSAPI也可以&#xff0c;如你用都用离线的话 leaflet加载geoserver的WMTS服务时TILEMATRIX字段 TILEMATR…

C语言——文件IO 【文件IO和标准IO区别,操作文件IO】open,write,read,dup2,access,stat

1.思维导图 2.练习 1&#xff1a;使用C语言编写一个简易的界面&#xff0c;界面如下 1&#xff1a;标准输出流 2&#xff1a;标准错误流 3&#xff1a;文件流 要求&#xff1a;按1的时候&#xff0c;通过printf输出数据&#xff0c;按2的时候&#xff0c;通过p…

C++实现图书管理系统(Qt C++ GUI界面版)

前瞻 本项目基于【C】图书管理系统(完整版) 图书管理系统功能概览&#xff1a; 登录&#xff0c;注册学生,老师借书&#xff0c;查看自己当前借书情况&#xff0c;还书。管理员增加书&#xff0c;查看当前借阅情况&#xff0c;查看当前所有借阅人&#xff0c;图书信息。 效果…