服务保护、分布式事务

简介: 本课程介绍微服务保护核心知识,涵盖雪崩问题、熔断降级、限流与线程隔离等解决方案。学习如何使用Sentinel实现熔断、降级(FallbackFactory)、限流及线程隔离配置,并掌握CAP原理与Seata分布式事务控制,提升系统稳定性与可靠性。

学习目标能够说出什么是微服务雪崩能够说出常用的微服务保护方案和技术方案能够说出什么是熔断降级能够基于FallbackFactory编写降级方法能够使用Sentinel配置熔断策略并测试通过能够使用Sentinel配置限流策略并测试通过能够基于Sentinel注解编写降级方法能够使用Sentinel配置线程隔离并测试通过能够说出CAP原理能够使用Seata实现分布式事务控制能够说出Seata AT模式的工作原理1 微服务保护1.1.微服务保护方案1.1.1 微服务雪崩问题上次课我们学习了微服务之间的远程调用,微服务通过远程调用进行协作完成业务流程,试想如果出现下边的现象会导致什么问题:假如商品服务业务并发较高,占用过多Tomcat连接。可能会导致商品服务的所有接口响应时间增加,延迟变高,甚至是长时间阻塞直至查询失败。此时查询购物车业务需要等待商品查询结果,从而导致购物车业务的响应时间也变长,甚至也阻塞直至无法访问。而此时如果查询购物车的请求较多,可能导致购物车服务的Tomcat连接占用较多,所有接口的响应时间都会增加,整个服务性能很差, 甚至不可用。依次类推,整个微服务群中与购物车服务、商品服务等有调用关系的服务可能都会出现问题,最终导致整个集群不可用。这就是级联失败问题,或者叫雪崩问题。【因为一个底层服务不可用,最终导致整个服务集群不可用】保证服务运行的健壮性,避免级联失败导致的雪崩问题,就属于微服务保护。这章我们就一起来学习一下微服务保护的常见方案以及对应的技术。1.1.2 微服务保护方案1.1.2.1 方案介绍AI:Spring cloud微服务保护的方案Spring Cloud微服务架构中的服务保护是非常重要的,它能够确保系统的稳定性和可用性,特别是在面对突发流量或者服务异常的情况下。常用的微服务保护方案包括但不限于以下几个方面:熔断 (Circuit Breaker) 熔断机制用于在服务出现问题时快速失败,避免调用链路中的服务相互等待,导致整体系统响应变慢甚至不可用。如何快速失败(fast fail)呢?当服务的错误率达到一定程度时,断路器(相当于保险丝)会打开,直接返回错误而不是尝试调用服务。一段时间后,断路器会处于半开状态尝试调用服务,如果服务恢复正常,则关闭断路器。

【知识拓展】AI:fast fail和safe fail区别答:Fast Fail(快速失败):旨在快速暴露问题,防止错误扩散或导致更严重的后果,如医疗、金融场景。缺点是:导致系统中断,影响用户体验【直接抛异常】Safe Fail(安全失败):旨在最大程度保证系统可用和安全性,如在线服务、云计算平台。缺点是:可能导致问题被掩盖,增加修复难度。【try-catch,返回一个默认值(即降级)】

由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。降级 (Degradation) 断路器会统计访问某个服务的请求数量,统计服务提供方的异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。降级逻辑 即提供一个简化的响应或者默认的响应来代替正常的服务调用。这样可以保证核心业务不受影响,非核心业务暂时被限制或关闭。

熔断后,接口还通吗?不通,直接异常降级后,接口还通吗? 通,但返回的是降级逻辑,即类似一个默认值,故业务逻辑不一定闭环,后续还需要人工补偿

超时 (Timeout) 设置合理的超时时间可以避免长时间等待响应导致的问题。当请求超时时,可以选择快速失败并返回错误信息,或者重试等策略。

常见的远程调用框架,都设置了超时机制。AI:目前Http、Dubbo、WebService都有超时机制吗?答:是的,HTTP、Dubbo 和 WebService 都支持超时机制,但它们的实现方式和配置方法有所不同HTTP:连接超时、读取超时Dubbo:服务调用超时(默认3s),超时后自动重试2次WebService:连接超时、读取超时

线程隔离 (Thread Isolation) 线程隔离是指为每个服务分配独立的线程池,这样即使某个服务出现问题也不会影响到其他服务。线程隔离的思想来自轮船的舱壁模式:轮船的船舱会被隔板分割为N个相互隔离的密闭舱,假如轮船触礁进水,只有损坏的部分密闭舱会进水,而其他舱由于相互隔离,并不会进水。这样就把进水控制在部分船体,避免了整个船舱进水而沉没。为了避免某个接口故障或压力过大导致整个服务不可用,我们可以限定每个接口可以使用的资源范围,也就是将其“隔离”起来。如图所示,我们给查询购物车业务限定可用线程数量上限为20,这样即便查询购物车的请求因为查询商品服务而出现故障,也不会导致服务器的线程资源被耗尽,不会影响到其它接口。限流 (Rate Limiting) 限流是最常见的服务保护措施之一,其目的是为了防止服务因为过大的流量而崩溃。对于某些关键资源或者参数的访问,可以采取特殊的限流措施来防止这些热点成为瓶颈。限流往往会有一个限流器,数量高低起伏的并发请求曲线,经过限流器就变的非常平稳。这就像是水电站的大坝,起到蓄水的作用,可以通过开关控制水流出的大小,让下游水流始终维持在一个平稳的量。可以通过以下几种方式进行限流(有兴趣的可以看看下面两种实现方案,前期可以仅做了解): 基于令牌桶算法:允许一定数量的请求通过,超出则拒绝或排队等待。 基于滑动窗口:在一段时间内对请求进行计数,超过阈值则触发限流。1.1.2.2 实现工具在Spring Cloud生态系统中,实现服务保护通常使用的工具包括:Hystrix: 提供了熔断、限流、超时等功能,是SpringCloud原生组件。Resilience4j: 是一个轻量级的库,提供了与Hystrix类似的功能,但设计更为现代和简洁。Sentinel: 阿里巴巴开源的一款流量控制组件,特别适合微服务架构下的流量管理,提供了限流、熔断、降级等多种服务保护功能,并且支持热更新规则。本课程讲解Sentinel。1.2 熔断降级1.2.1. 方案介绍熔断降级是解决服务集群雪崩问题的重要手段,包括熔断和降级两个方案。熔断是由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。熔断发生在服务调用方即客户端。

这么多报错(慢请求)是吧?行、都别玩了

降级是当遇到访问失败可以快速返回一些默认数据或者友好提示,用户体验会更好。熔断降级结合后是当线路断开后直接走降级线路避免再次去请求失败线路。降级方法需要在服务调用方即客户端实现。

这么多报错(慢请求)是吧?大哥你这样我就要挂了,小弟帮我顶顶(还有部分可以玩)

断路器控制熔断和放行的流程如下:断路器包括三个状态:closed:关闭状态【默认】,断路器放行所有请求,并开始统计异常比例、慢请求比例、异常数。超过阈值则切换到open状态open:打开状态,服务调用被熔断,访问被熔断服务的所有请求会被拒绝,快速失败,直接走降级逻辑。Open状态5秒后会进入half-open状态half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。请求成功:则切换到closed状态请求失败:则切换到open状态实现熔断降级做两件事:编写服务降级逻辑:就是服务调用失败后的处理逻辑,根据业务场景,可以抛出异常,也可以返回友好提示或默认数据。异常统计和熔断:统计服务提供方的异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。这里我们用Sentinel完成。1.2.2. Sentinel安装与集成1.2.2.1 切换分支将hmall-micro代码环境切换到dev_02分支。注意:切换分支前要提交原当前分支的代码。每位学生在dev_02分支练习完成后提交代码并切换回dev_01分支继续未完成的任务

工作中也经常这样来回切换分支,因为不同需求在不同分支里,我们经常都是并行开发大家入职后,也可能同时负责3-4个项目,所以尽早习惯【多线程并行的开发模式】

1.2.2.2 安装Sentinel实现服务保护的工具有很多,Spring Cloud Alibaba技术栈中Sentinel是实现服务保护的中间件。Sentinel是阿里巴巴开源的一款服务保护框架,目前已经加入Spring Cloud Alibaba中。官方网站:

home | Sentinel

home

Sentinel

介绍

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件) - alibaba/Sentinel

GitHub

Sentinel 的使用可以分为两个部分:核心库(Jar包):不依赖任何框架/库,能够运行于Java8及以上的版本的运行时环境,同时对 Dubbo/Spring Cloud 等框架也有较好的支持。在项目中引入依赖即可实现服务限流、隔离、熔断等功能。控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。为了方便监控微服务,我们先把Sentinel的控制台搭建出来。课前提供的虚拟机已经安装了sentinel,如下图:使用课前提供的虚拟机需要设置sentinel容器的时区,如下:先启动sentinel登录sentinel容器并设置时区进入容器:docker exec -it sentinel-dashboard /bin/bash执行命令:ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezon设置完成效果如下 :如果未使用课前提供的虚拟机,需要参考下边的内容安装sentinel:1)下载jar包下载地址:https://github.com/alibaba/Sentinel/releases也可以直接使用课前资料提供的版本:2)运行将jar包拷贝到 虚拟机/data/soft/sentinel目录下重命名为sentinel-dashboard.jar:创建Dockerfile文件执行命令创建镜像:创建并启动容器:其它启动时可配置参数可参考官方文档:官网文档链接3)访问访问:http://192.168.101.68:9090/ 页面,就可以看到sentinel的控制台了:需要输入账号和密码,默认都是:sentinel登录后,即可看到控制台,默认会监控sentinel-dashboard服务本身:本地运行sentinel如果在测试时发现虚拟中的sentinel不能用,可以本地运行sentinel。将sentinel的jar包放在任意非中文、不包含特殊字符的目录下,重命名为sentinel-dashboard.jar:然后运行如下命令启动控制台:访问:http://localhost:8090/ 页面1.2.2.3 项目集成Sentinel在虚拟机启动sentinel【上面已经执行过,这里是再次提醒、确认一下】接下来,我们在项目中集成 sentinel,我们在哪个项目中集成 sentinel?sentinel要完成熔断降级,熔断是在服务调用方,所以针对购物车服务请求商品服务实现熔断就需要在购物车服务集成 sentienl。

这里可能部分同学有疑问,问什么不是服务提供方呢?所以我们顺便推导一下,假设是提供方熔断:(1)提供方是熔断了,但是上游调用方还是有大量请求,压力依然存在,只是加快了下游的响应速度,前提是牺牲了原有的业务逻辑实现,并不能保障整体微服务的可靠性(2)调用方熔断,就是我根本不调用你下游(你此刻慢、报错多那我就先不调用你),而是返回一个默认逻辑,这个默认逻辑实现应该由接口提供方实现

我们在cart-service模块中整合sentinel,连接sentinel-dashboard控制台,步骤如下: 1)引入sentinel依赖2)配置控制台修改application.yaml文件,添加下面内容:如果是在本机运行的sentinel要配置:3)访问cart-service的任意端点重启cart-service、item-service,然后访问查询购物车接口:swagger链接sentinel的客户端就会将服务访问的信息提交到sentinel-dashboard控制台。并展示出统计信息:点击簇点链路菜单,会看到下面的页面:所谓簇点链路,就是单机调用链路,是一次请求进入服务后经过的每一个被Sentinel监控的资源。默认情况下,Sentinel会监控SpringMVC的每一个Endpoint(接口)。因此,我们看到/carts这个接口路径就是其中一个簇点,我们可以对其进行限流、熔断、降级、隔离等保护措施,稍后会详细讲解。1.2.3. 实现降级1.2.3.1 开启sentinel下边我们先编写降级逻辑,再实现服务熔断。

AI(Cursor)提示詞帮我在已有工程里,对于itemclient实现降级策略,技术使用Sentinel,注意实现方案是implements FallbackFactory,降级类写在api的工程里,并最终在cart-service调用item-service时使用

首先配置Feign使用Sentinel:在购物车服务application.yml中配置如下(默认已写好):

YAML

复制代码

1

2

3

feign:

 sentinel:

   enabled: true # 开启feign对sentinel的支持

相关文章
|
iOS开发
SwiftUI极简教程13:NavigationView导航栏使用
SwiftUI极简教程13:NavigationView导航栏使用
2700 2
SwiftUI极简教程13:NavigationView导航栏使用
|
前端开发 安全 JavaScript
【Message 全局提示】基于 React 实现 Message 组件
使用 ReactDOM.createRoot、React.forwardRef、React.useImperativeHandle 实现 Message 组件。使用 Web Crypto API 生成符合密码学要求的安全的随机 ID。
|
移动开发 前端开发 JavaScript
HTML - Canvas 使用画布旋转文本
HTML - Canvas 使用画布旋转文本
497 0
HTML - Canvas 使用画布旋转文本
|
网络协议 测试技术 网络安全
|
4月前
|
监控 Java 测试技术
OOM排查之路:一次曲折的线上故障复盘
本文记录了一次Paimon数据湖与RocksDB集成服务线上频繁OOM的排查历程。通过分析线程暴增、堆外内存泄漏,最终定位到SDK中RocksDB的JNI内存未释放问题,并借助Flink重构写入链路彻底解决。分享了MAT、NMT、async-profiler等工具的实战经验与排查思路,为类似技术栈提供借鉴。
OOM排查之路:一次曲折的线上故障复盘
|
4月前
|
人工智能 JSON 数据挖掘
大模型应用开发中MCP与Function Call的关系与区别
MCP与Function Call是大模型应用中两大关键技术。前者为跨模型标准化通信协议,实现工具与模型解耦;后者是模型调用外部功能的内置机制。二者互补协作,推动AI应用向更开放、灵活、可扩展的方向发展。
|
4月前
|
传感器 人工智能 算法
学生二次开发机器人平台完全指南:从入门到实战的选型与开发路径
本文系统解析适合学生二次开发的机器人平台,涵盖开放性、学习曲线与成本平衡等核心特征,对比服务机器人、开源底盘、双足/四足平台及DIY套件,指导学生按预算、技术方向与应用场景科学选型,并提供实战开发路径与职业发展建议。
|
4月前
|
XML 算法 安全
详解RAG五种分块策略,技术原理、优劣对比与场景选型之道
RAG通过检索与生成结合,提升大模型在企业场景的准确性与安全性。分块策略是其核心,直接影响检索效果与答案质量。本文系统解析五种主流分块方法——固定大小、语义、递归、基于结构及LLM分块,对比优缺点与适用场景,助力构建高效、可靠的RAG系统。
|
安全 Android开发 iOS开发
Android vs. iOS:构建生态差异与技术较量的深度剖析###
本文深入探讨了Android与iOS两大移动操作系统在构建生态系统上的差异,揭示了它们各自的技术优势及面临的挑战。通过对比分析两者的开放性、用户体验、安全性及市场策略,本文旨在揭示这些差异如何塑造了当今智能手机市场的竞争格局,为开发者和用户提供决策参考。 ###
|
存储 网络协议 API
Cpp网络编程Winsock API
本文详细介绍了使用Winsock API进行C++网络编程的过程,通过具体实例实现了一个基于TCP协议的C/S架构通信demo。文章从服务端与客户端两方面展开,涵盖网络库初始化、套接字创建、绑定IP与端口、监听与连接、数据收发到关闭连接等关键步骤。重点解析了`WSAStartup`、`socket`、`bind`、`listen`、`accept`、`connect`、`send`和`recv`等函数的使用方法及注意事项,并对比了标准库与Winsock库在链接时的区别。适合初学者了解Winsock网络编程基础。
619 35