服务保护、分布式事务

简介: 本章介绍微服务保护机制,重点解决因单个服务故障引发的雪崩问题。通过熔断、降级、超时、线程隔离和限流五大方案,结合Sentinel工具实现服务稳定性控制。课程涵盖原理讲解、环境搭建与项目集成,帮助开发者构建高可用微服务系统。(238字)

1 微服务保护
1.1.微服务保护方案
1.1.1 微服务雪崩问题
上次课我们学习了微服务之间的远程调用,微服务通过远程调用进行协作完成业务流程,试想如果出现下边的现象会导致什么问题:
假如商品服务业务并发较高,占用过多Tomcat连接。可能会导致商品服务的所有接口响应时间增加,延迟变高,甚至是长时间阻塞直至查询失败。
此时查询购物车业务需要等待商品查询结果,从而导致购物车业务的响应时间也变长,甚至也阻塞直至无法访问。而此时如果查询购物车的请求较多,可能导致购物车服务的Tomcat连接占用较多,所有接口的响应时间都会增加,整个服务性能很差, 甚至不可用。

依次类推,整个微服务群中与购物车服务、商品服务等有调用关系的服务可能都会出现问题,最终导致整个集群不可用。

这就是级联失败问题,或者叫雪崩问题。【因为一个底层服务不可用,最终导致整个服务集群不可用】
保证服务运行的健壮性,避免级联失败导致的雪崩问题,就属于微服务保护。这章我们就一起来学习一下微服务保护的常见方案以及对应的技术。
1.1.2 微服务保护方案
1.1.2.1 方案介绍
AI:Spring cloud微服务保护的方案
Spring Cloud微服务架构中的服务保护是非常重要的,它能够确保系统的稳定性和可用性,特别是在面对突发流量或者服务异常的情况下。常用的微服务保护方案包括但不限于以下几个方面:

  1. 熔断 (Circuit Breaker) 熔断机制用于在服务出现问题时快速失败,避免调用链路中的服务相互等待,导致整体系统响应变慢甚至不可用。
    如何快速失败(fast fail)呢?当服务的错误率达到一定程度时,断路器(相当于保险丝)会打开,直接返回错误而不是尝试调用服务。一段时间后,断路器会处于半开状态尝试调用服务,如果服务恢复正常,则关闭断路器。
    【知识拓展】
    AI:fast fail和safe fail区别
    答:
    Fast Fail(快速失败):旨在快速暴露问题,防止错误扩散或导致更严重的后果,如医疗、金融场景。缺点是:导致系统中断,影响用户体验【直接抛异常】
    Safe Fail(安全失败):旨在最大程度保证系统可用和安全性,如在线服务、云计算平台。缺点是:可能导致问题被掩盖,增加修复难度。【try-catch,返回一个默认值(即降级)】
    由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。

  2. 降级 (Degradation) 断路器会统计访问某个服务的请求数量,统计服务提供方的异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。
    降级逻辑 即提供一个简化的响应或者默认的响应来代替正常的服务调用。这样可以保证核心业务不受影响,非核心业务暂时被限制或关闭。
    熔断后,接口还通吗?
    不通,直接异常
    降级后,接口还通吗?
    通,但返回的是降级逻辑,即类似一个默认值,故业务逻辑不一定闭环,后续还需要人工补偿

  3. 超时 (Timeout) 设置合理的超时时间可以避免长时间等待响应导致的问题。当请求超时时,可以选择快速失败并返回错误信息,或者重试等策略。
    常见的远程调用框架,都设置了超时机制。
    AI:目前Http、Dubbo、WebService都有超时机制吗?
    答:是的,HTTP、Dubbo 和 WebService 都支持超时机制,但它们的实现方式和配置方法有所不同
    HTTP:连接超时、读取超时
    Dubbo:服务调用超时(默认3s),超时后自动重试2次
    WebService:连接超时、读取超时

  4. 线程隔离 (Thread Isolation) 线程隔离是指为每个服务分配独立的线程池,这样即使某个服务出现问题也不会影响到其他服务。
    线程隔离的思想来自轮船的舱壁模式:

轮船的船舱会被隔板分割为N个相互隔离的密闭舱,假如轮船触礁进水,只有损坏的部分密闭舱会进水,而其他舱由于相互隔离,并不会进水。这样就把进水控制在部分船体,避免了整个船舱进水而沉没。
为了避免某个接口故障或压力过大导致整个服务不可用,我们可以限定每个接口可以使用的资源范围,也就是将其“隔离”起来。

如图所示,我们给查询购物车业务限定可用线程数量上限为20,这样即便查询购物车的请求因为查询商品服务而出现故障,也不会导致服务器的线程资源被耗尽,不会影响到其它接口。

  1. 限流 (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中。官方网站:链接https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
Sentinel 的使用可以分为两个部分:
● 核心库(Jar包):不依赖任何框架/库,能够运行于Java8及以上的版本的运行时环境,同时对 Dubbo/Spring Cloud 等框架也有较好的支持。在项目中引入依赖即可实现服务限流、隔离、熔断等功能。
● 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。
为了方便监控微服务,我们先把Sentinel的控制台搭建出来。
课前提供的虚拟机已经安装了sentinel,如下图:

使用课前提供的虚拟机需要设置sentinel容器的时区,如下:
先启动sentinel
docker start sentinel-dashboard
登录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文件
FROM openjdk:11-jdk

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezo
ARG SENTINEL_VERSION=1.8.6

copy sentinel jar

ADD ./sentinel-dashboard.jar /home/sentinel-dashboard.jar
RUN chmod -R +x /home/sentinel-dashboard.jar

ENTRYPOINT ["sh","-c","java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar $JAVA_OPTS /home/sentinel-dashboard.jar"]
执行命令创建镜像:
docker build -t sentinel-dashboard .
创建并启动容器:
docker run --name sentinel-dashboard -d -p 9090:8090 sentinel-dashboard:latest
其它启动时可配置参数可参考官方文档:官网文档链接

3)访问
访问:http://192.168.101.68:9090/ 页面,就可以看到sentinel的控制台了:

需要输入账号和密码,默认都是:sentinel
登录后,即可看到控制台,默认会监控sentinel-dashboard服务本身:

本地运行sentinel
如果在测试时发现虚拟中的sentinel不能用,可以本地运行sentinel。
将sentinel的jar包放在任意非中文、不包含特殊字符的目录下,重命名为sentinel-dashboard.jar:

然后运行如下命令启动控制台:
java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
访问:http://localhost:8090/ 页面
1.2.2.3 项目集成Sentinel
在虚拟机启动sentinel【上面已经执行过,这里是再次提醒、确认一下】
docker start sentinel-dashboard
接下来,我们在项目中集成 sentinel,我们在哪个项目中集成 sentinel?
sentinel要完成熔断降级,熔断是在服务调用方,所以针对购物车服务请求商品服务实现熔断就需要在购物车服务集成 sentienl。
这里可能部分同学有疑问,问什么不是服务提供方呢?所以我们顺便推导一下,假设是提供方熔断:
(1)提供方是熔断了,但是上游调用方还是有大量请求,压力依然存在,只是加快了下游的响应速度,前提是牺牲了原有的业务逻辑实现,并不能保障整体微服务的可靠性
(2)调用方熔断,就是我根本不调用你下游(你此刻慢、报错多那我就先不调用你),而是返回一个默认逻辑,这个默认逻辑实现应该由接口提供方实现
我们在cart-service模块中整合sentinel,连接sentinel-dashboard控制台,步骤如下: 1)引入sentinel依赖


com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel

2)配置控制台
修改application.yaml文件,添加下面内容:
spring:
cloud:
sentinel:
transport:
dashboard: 192.168.101.68:9090
client-ip: 192.168.101.1
http-method-specify: true # 开启请求方式前缀可根据http请求方法区分簇点链路
如果是在本机运行的sentinel要配置:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8090
http-method-specify: true # 开启请求方式前缀可根据http请求方法区分簇点链路
3)访问cart-service的任意端点
重启cart-service、item-service,然后访问查询购物车接口:swagger链接

sentinel的客户端就会将服务访问的信息提交到sentinel-dashboard控制台。并展示出统计信息:

点击簇点链路菜单,会看到下面的页面:

所谓簇点链路,就是单机调用链路,是一次请求进入服务后经过的每一个被Sentinel监控的资源。默认情况下,Sentinel会监控SpringMVC的每一个Endpoint(接口)。
因此,我们看到/carts这个接口路径就是其中一个簇点,我们可以对其进行限流、熔断、降级、隔离等保护措

相关文章
|
程序员
面试高频题:开发人员说不是bug,测试如何答复?
面试高频题:开发人员说不是bug,测试如何答复?
612 0
|
4月前
|
Arthas 存储 运维
记Arthas实现一次CPU排查与代码热更新
本文介绍如何使用Arthas排查线上Java应用CPU占用过高问题,结合thread、watch、jad等指令定位阻塞线程与异常代码,实现无需重启服务的热更新修复,并通过profile生成火焰图进行性能分析,提升线上问题排查效率。
|
3月前
|
缓存 安全 网络安全
阿里云 ESA (边缘安全加速) 免费版2026年03月15日截止申请
阿里云ESA免费版现已向中国站用户开放,支持无限流量与国内节点加速(需备案),告别CF国内慢速。注册账号并实名即可申请,享5Mbps峰值带宽、免费HTTPS、缓存优化及基础安全防护,助力网站高效稳定运行。
1486 16
|
4月前
|
人工智能 自然语言处理 监控
AI客服机器人部署入门:意图识别模型话术配置3步快速上线
部署AI客服机器人需三步:构建高精度意图识别模型实现“听懂”,配置人性化话术确保“答好”,通过测试与数据驱动迭代保障“用稳”。该方法可系统性提升自动化解决率与用户体验,是企业客服智能化、降本增效的可靠路径。
489 3
|
4月前
|
安全 数据安全/隐私保护
RBAC权限模型
RBAC(基于角色的访问控制)通过角色管理权限,实现用户、角色、权限与资源的分离。其核心原则包括最小权限、职责分离与数据抽象,分为RBAC0至RBAC3四个层级,逐步支持角色继承与动态静态职责分离,提升系统安全与管理效率。
|
数据采集 机器学习/深度学习 算法
【优秀设计案例】基于K-Means聚类算法的球员数据聚类分析设计与实现
本文通过K-Means聚类算法对NBA球员数据进行聚类分析,旨在揭示球员间的相似性和差异性,为球队管理、战术决策和球员评估提供数据支持,并通过特征工程和结果可视化深入理解球员表现和潜力。
843 1
【优秀设计案例】基于K-Means聚类算法的球员数据聚类分析设计与实现
|
12月前
|
人工智能 小程序 API
【一步步开发AI运动APP】八、自定义姿态动作识别检测——之姿态相似度比较
本文介绍了如何通过姿态相似度比较技术简化AI运动应用开发。相比手动配置规则,插件`pose-calc`提供的姿态相似度比较器可快速评估两组人体关键点的整体与局部相似度,降低开发者工作量。文章还展示了在`uni-app`框架下调用姿态比较器的示例代码,并提供了桌面辅助工具以帮助提取标准动作样本,助力开发者打造性能更优、体验更好的AI运动APP。
|
Shell Linux 调度
cgroup 资源控制介绍
cgroup 资源控制介绍
|
C# 图形学
unity抛物线的制作
该教程展示了如何在Unity中使用LineRenderer组件和C#脚本绘制抛物线。具体步骤如下:创建一个空物体并添加LineRenderer组件,挂载提供的`SeletParabola`脚本;新建两个Cube作为起点和终点,并将其拖到脚本对应的公共变量上。运行后即可看到从起点到终点的抛物线效果。代码通过计算抛物线上的点并设置给LineRenderer来实现这一效果。此外,还可以为LineRenderer添加贴图以增强视觉效果。
|
存储 缓存 监控
【赵渝强老师】HBase的体系架构
本文介绍了HBase的体系架构,包括HMaster、RegionServer和ZooKeeper的主要功能。HMaster负责Region的分配和管理,RegionServer处理数据的读写操作,ZooKeeper维护集群状态并协调分布式系统的运行。文章还详细解释了Region、WAL预写日志、Block Cache读缓存和MemStore写缓存的作用。
763 0

热门文章

最新文章