Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(二))(JMeter模拟测试)

简介: Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)(二)

四. Sentinel普通流控

1. 普通流控定义

/**

* flow 流控规则,详情查看RuleType

*/

FLOW("flow", FlowRule.class)


作用在网关的流控称之为网关流控,相对的作用在除网关之外的微服务流控这里称为普通流控


在上一个章节中,发现网关流控并不是万能的,像认证中心youlai-auth调用系统服务youlai-admin这种微服务相互调用而不走网关的情况,网关流控表示无能为力,但不可否认的是网关流控确实能够应对大多数场景的流控。


所以在像上文中的网关流控无能为力的案例,则需要普通流控的救场。


2. 普通流控的规则

Field 说明 默认值

resource 资源名,资源名是限流规则的作用对象

count 限流阈值

grade 限流阈值类型,QPS 【1】或线程数模式【0】 QPS 模式

limitApp 流控针对的调用来源 default,代表不区分调用来源

strategy 判断的根据是资源自身,还是根据其它关联资源 (refResource),还是根据链路入口 根据资源本身

controlBehavior 流控效果(直接拒绝 / 排队等待 / 慢启动模式) 直接拒绝

3. 导入依赖

com.alibaba.cloud

spring-cloud-starter-alibaba-sentinel


com.alibaba.csp

sentinel-datasource-nacos



4. 微服务配置

spring:

 application:

   name: youlai-admin

 cloud:

   nacos:

     discovery:

       server-addr: http://localhost:8848

     config:

       server-addr: ${spring.cloud.nacos.discovery.server-addr}

       file-extension: yaml

   sentinel:

     enabled: true

     eager: true # 取消控制台懒加载,项目启动即连接Sentinel

     transport:

       client-ip: localhost

       dashboard: localhost:8080

     datasource:

       # 限流规则,flow为key,随便定义

       flow:

         nacos:

           server-addr: ${spring.cloud.nacos.discovery.server-addr}

           dataId: ${spring.application.name}-flow-rules

           groupId: SENTINEL_GROUP

           data-type: json

           rule-type: flow


5. Nacos添加流控规则

进入Nacos控制台,添加规则配置文件,接着上文的案例,在认证的时候,youlai-auth需通过feign调用youlai-admin根据用户名获取用户信息。

微信图片_20230710074742.png



进入Sentinel控制台查看,除了刚在Nacos添加的规则之外,还可以看到普通流控面板和网关流控面板的区别

微信图片_20230710074745.png



6. 普通流控测试

经过网关流控限制只能有10条请求到youlai-auth,接下来youlai-auth调用youlai-admin链路中,因为限制了youlai-admin的QPS上限为5,所以最终应该是只有5条请求是有效的。看测试结果:

微信图片_20230710074749.png微信图片_20230710074752.png





7. 自定义异常

上面被限流后的异常信息,显然不是想要的,那么如何自定义普通流控异常呢?


**解决方案:**实现BlockExceptionHandler接口


@Component

public class DefaultBlockExceptionHandler implements BlockExceptionHandler {

   @Override

   public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {

       response.setStatus(HttpStatus.ok().status());

       response.setCharacterEncoding("UTF-8");

       response.setContentType("application/json;charset=utf-8");

       if(e instanceof FlowException){

           // objectMapper.writeValue 用于将java对象转位JSON格式返回调用方

           new ObjectMapper().writeValue(response.getWriter(), Result.failed(ResultCode.FLOW_LIMITING));

       }

   }

}


为了测试普通流控,首先关闭网关流控,排除一些异常干扰


微信图片_20230710074836.png


添加获取当前登录用户信息的HTTP请求


微信图片_20230710074839.png


因为此HTTP接口需要认证,所以需要在请求头添加token。鼠标右击HTTP请求->添加->配置元件->HTTP信息头管理

微信图片_20230710074842.png



HTTP信息头管理器添加token

微信图片_20230710074909.png



执行线程组,查看自定义异常生效

微信图片_20230710074911.png



五. Sentinel熔断降级

1. 熔断降级概述

微服务架构都是分布式的,不同服务相互调用,组成复杂的调用链路。复杂的链路上某一环不稳定,就可能层层级联,最终导致整个链路都不可用。因此需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定的调用,避免局部不稳定因素导致正题的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。


2. 熔断策略

微信图片_20230710074937.png


Sentinel提供了三种熔断策略:


慢调用比例: 请求响应时间大于设置的RT(即最大的响应时间)则统计为慢调用。触发此熔断策略的条件需要满足两个条件,一是单位统计时长(statIntervalMs)内请求数大于设置的最小请求数,二是慢调用的比例大于阈值,接下来在熔断时长的范围内请求会自动的被熔断。过了熔断时长后,熔断器进入探测恢复状态(HALF-OPEN状态),若接下来的一个请求响应时间小于设置的慢调用RT则结束熔断,若大于设置的慢调用RT则会再次被熔断。

异常比例:当单位统计时长请求数大于设置的最小请求数,并且异常的比例大于阈值,则接下来的熔断时长内请求会被自动熔断。

异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。

3. 熔断降级规则

熔断降级规则(DegradeRule)包含下面几个重要的属性:


Field 说明 默认值

resource 资源名,即规则的作用对象

grade 熔断策略,支持慢调用比例/异常比例/异常数策略 慢调用比例

count 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值

timeWindow 熔断时长,单位为 s

minRequestAmount 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) 5

statIntervalMs 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) 1000 ms

slowRatioThreshold 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

4. 微服务配置

spring:

 cloud:

   sentinel:

       # 降级规则,degrade为降级key,随便取名

       degrade:

         nacos:

           server-addr: ${spring.cloud.nacos.discovery.server-addr}

           dataId: ${spring.application.name}-degrade-rules

           groupId: SENTINEL_GROUP

           data-type: json

           rule-type: degrade


5. Nacos添加熔断降级规则

微信图片_20230710074948.png


方便看到异常熔断的效果,选择了异常数的熔断策略,毕竟数数比计算比例简单多了。资源名为getCurrentUser是怎么回事,不急下文提到。总之这里的配置的大概意思就是说针对getCurrentUser资源,如果请求该接口出现了异常,则进行熔断,熔断时长为5秒。


6. 熔断异常模拟

先模拟一段在运行时发生异常的代码,在获取当前登录用户信息的接口埋个雷吧,注意到@SentinelResource注解中的value值getCurrentUser,也就是资源名称,联系上文,降级规则就是针对这个接口的方法。和上面在普通流控测试使用的是请求的路径不同,这里显示指定了资源名称和降级规则配置去做匹配。


微信图片_20230710075005.png


@SentinelResource注解中的属性除了定义资源名的属性值value,还有两个属性有关降级处理分别是blockHandlerClass和blockHandler。意思是在单位时间接口异常数超过设置的阈值后进入熔断,在熔断时长(上面降级规则中设置的是5秒)范围内,再有请求过来访问该接口时,不会再走接口方法体内的逻辑。因为前面几次接口出现异常,那么敢断定接下来短时间内大概率还是会发生异常,所以索性就把后续的请求拦截避免,这也是熔断的意义。


在5秒的熔断时长内,如果再有请求访问该接口则会走降级的逻辑,也就是上图中指定的UserBlockHandler#handleGetCurrentUserBlock降级处理方法。


微信图片_20230710075040.png


7. 熔断降级测试

在测试前,需要关闭网关那边流控,排除一些异常情况下的干扰。还有为了方便在JMeter查看结果,临时关闭全局异常处理器GlobalExceptionHandler。


还是拿上一节配置好的测试普通流控的线程组,获取登录用户的信息来作为熔断降级的测试案例,先看一下线程组的设置:


线程数为10,达到了熔断降级最小请求数(规则配置的5)的要求


微信图片_20230710075053.png


获取登陆用户信息的接口信息

微信图片_20230710075056.png



请求头添加token

微信图片_20230710075101.png



测试线程组配置好之后看看使用不使用熔断降级和使用熔断降级的区别:


不使用熔断降级

配置中关闭Sentinel


sentinel:

 enabled: false

1

2

微信图片_20230710075124.png微信图片_20230710075134.png




发现了吗?这种请求异常处理模式头铁啊,即使撞了南墙也不会回头,下次继续撞,下下次继续撞。ok,你没关系,那你有考虑一直被你撞的墙(服务器)了没?


使用熔断降级

配置中开启Sentinel


sentinel:

 enabled: true

1

2

微信图片_20230710075153.png微信图片_20230710075156.png




通过日志可以看到进入主线代码的只有一次,后续的请求直接进入降级支线。

微信图片_20230710075215.png



过了熔断时长5秒后,熔断器进入探测恢复状态(HALF-OPEN状态),这时候如果一个请求到主线没异常,关闭熔断器,让后续的请求都到主线过来;如果还是异常,打开熔断器。


六. Sentinel整合Feign熔断降级

1. Feign与Sentinel整合意义

在微服务架构中,声明式调用Feign在微服务之间调用充当重要的角色,在使用Feign的过程中如果为了系统的健壮性,一定会考虑如果因目标服务异常调用失败后的处理。


说到这里,相信对微服务有些了解的童鞋对下面的代码很熟悉:

微信图片_20230710075231.png微信图片_20230710075234.png





上面两张图反应了Feign客户端在远程调用目标服务失败后,继而选择了降级的逻辑,像做人一样随时要给自己留一条后路,也就是稳,折射到程序亦是如此。这里只是一个降级的自定义异常返回,实际情况根据业务而定。


看到上面的代码,Feign在设计上就支持了降级的处理。这时候相信大家都会有一个疑问,Feign本身已经支持降级,那还需要Sentinel做什么?


换句话说可能会好理解一点,Sentinel给Feign带来了什么好处?


这个问题其实不难理解,先直接从字面上切入。


Feign是能够做到降级,Sentinel能够实现熔断降级,突显出来也就是熔断这一词,其中熔断的具体表象是怎样的?举个栗子说明:


假如客户端a通过feign调用b服务100次,此时b服务故障


没有熔断


a的第1次请求走到b服务跟前,看着b躺在地上没动静,响应给客户端a说b没动静,让客户端a自己看着办吧。后面如此往复99次,每次a都需要走到b的面前然后再响应给客户端a,并告知b故障了。


有熔断


a的第1次请求走到b服务跟前,看着b躺在地上没动静,这时候a就比较机智,判断b服务没有一时半刻是起不来了,就响应给客户端a并说这一时半刻钟的请求你自己看着处理吧,没有必要再到b面前,后面的99次请求就不会再到服务b那里了,省时省力。


想通过上面的举例说明熔断的意义和作用,因为Feign已经支持了降级,那再搭配上Sentinel的熔断,岂不是如虎添翼?


接下来将通过有来项目中的实例,认证中心【youlai-auth】在登录时需要远程feign调用系统服务【youlai-admin】的根据用户名获取用户信息的接口,来说明Sentinel如何整合Feign实现熔断降级及熔断降级的魅力。


2. 导入依赖

youlai-auth添加Sentinel和Nacos持久化规则依赖


   com.alibaba.cloud

   spring-cloud-starter-alibaba-sentinel


   com.alibaba.csp

   sentinel-datasource-nacos




3. 微服务配置

youlai-auth开启Feign对Sentinel的支持


spring:

 application:

   name: youlai-auth

 cloud:

   sentinel:

     enabled: true

     eager: true # 取消控制台懒加载,项目启动即连接Sentinel

     transport:

       client-ip: localhost

       dashboard: localhost:8080

     datasource:

       # 降级规则

       degrade:

         nacos:

           server-addr: ${spring.cloud.nacos.discovery.server-addr}

           dataId: ${spring.application.name}-degrade-rules

           groupId: SENTINEL_GROUP

           data-type: json

           rule-type: degrade

# Feign开启对Sentinel支持

feign:

 sentinel:

   enabled: true



4. 熔断降级规则

在Nacos控制台添加youlai-auth的降级规则


微信图片_20230710075255.png


[

{

 "resource": "GET:http://youlai-admin/api.admin/v1/users/username/{username}",

 "grade": 2,

 "count": 1,

 "timeWindow": 5

}

]


注意资源名称的生成规则,上面配置的意思是如果单位时间内出现了1次异常数,那没接下来5秒的时间窗口范围内的请求,因为熔断器打开,请求直接走降级逻辑。


5. 熔断降级测试

首先要模拟系统服务的根据用户名获取用户信息的接口异常,具体如下图:

微信图片_20230710075300.png



配置JMeter线程组,单位时间1s内执行10个请求,具体配置在普通流控有说明,这里不做赘述。

/微信图片_20230710075303.png



结果在youlai-auth确实执行了10次请求,因为目标服务的异常走了降级的逻辑

微信图片_20230710075306.png



但是真正进入youlai-admin的根据用户名获取用户信息的接口方法却只有1次,后续的9次请求直接走feign客户端的降级逻辑


微信图片_20230710075340.png


上面的测试结果验证了Feign整合Sentinel之后实现了熔断和降级,至此Feign不再孤军奋战。


七. 结语

本文就Sentinel的流控、熔断降级从实战的角度去逐一验证。网关流控、普通流控能够在有限的资源能力保障系统的稳定运行,熔断降级能够在系统故障时提供兜底的处理逻辑保证系统的健壮性,支持降级的Feign整合Sentinel之后get到熔断的技能,至此熔断降级双剑合璧。


以前觉得微服务的限流、熔断降级是可有可无的存在,所以在开源项目中一直迟迟没有做相关的整合,当真正理解这其中的利害关系之后,微服务离不开这些。


当然本文提到的Sentinel功能的冰山一角,像限流延伸的还有热点key、IP限流、参数限流等等,具体选择使用根据场景,功能丰富,总会有你需要的。而且容易上手,是一个很不错的框架,内部的实现原理和还有算法很有必要去了解深入下。


如果有问题,欢迎加我微信(微信号:haoxianrui)


八. 附录

本文涉及的源码地址:


平台 地址

github https://github.com/hxrui/youlai-mall

gitee https://gitee.com/youlaitech/youlai-mall

文中的Sentinel规则配置已放置在项目document/nacos/SENTINEL_GROUP.zip,导入到Nacos控制台即可


微信图片_20230710075353.png


当然你也可以本地启动Sentinel控制台,已经把官方的jar包放置在项目youlai-middleware/setinel/sentinel-dashboard-1.8.1.jar


cd youlai-middleware/setinel

java -jar sentinel-dashboard-1.8.1.jar

1

2

微信图片_20230710075356.png


本地访问 http://localhost:8080即可进入Sentinel控制台



相关文章
|
11月前
|
JSON 测试技术 API
Apipost与Apifox测试功能对决,谁更适合开发者?
在API开发中,调试工具的选择至关重要。本文对比了国产工具Apipost与Apifox的功能差异,涵盖调试能力、环境管理、团队协作、文档生成、自动化测试等方面。Apifox在细节处理、协作支持及生态集成上表现更优,适合复杂项目与团队开发;而Apipost则适合基础调试需求。通过全面评估,开发者可依据项目特点选择合适工具,提升开发效率与质量。
Apipost与Apifox测试功能对决,谁更适合开发者?
|
11月前
|
人工智能 测试技术 项目管理
测试不再碎片化:AI智能体平台「项目资料套件」功能上线!
在实际项目中,需求文档分散、整理费时、测试遗漏等问题常困扰测试工作。霍格沃兹推出AI智能体测试平台全新功能——项目资料套件,可将多个关联文档打包管理,并一键生成测试用例,提升测试完整性与效率。支持套件创建、文档关联、编辑删除及用例生成,适用于复杂项目、版本迭代等场景,助力实现智能化测试协作,让测试更高效、更专业。
|
11月前
|
存储 人工智能 测试技术
用AI提升测试效率:智能体平台的「需求文档管理」功能上线啦!
霍格沃兹测试开发学社推出AI智能体测试平台,全新「需求文档管理」功能助力高效测试准备。集中管理需求文档,支持多种上传方式,智能生成测试用例,提升测试效率与准确性,助力迈向智能化测试新时代。
|
10月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
805 2
|
11月前
|
人工智能 自然语言处理 前端开发
深度解析Playwright MCP:功能、优势与挑战,AI如何提升测试效率与覆盖率
Playwright MCP通过AI与浏览器交互,实现自然语言驱动的自动化测试。它降低门槛、提升效率,助力测试工程师聚焦高价值工作,是探索性测试与快速验证的新利器。
|
11月前
|
测试技术
自动化测试登录后的功能
在自动化测试的时候,往往许多功能需要登录以后才可以进行操作的,在这里我介绍一种方法,在登录以后将Cookies信息存入本地文件,在测试登录以后操作的时候再从本地文件把信息调出来存入Cookies
208 4
|
敏捷开发 运维 数据可视化
DevOps看板工具中的协作功能:如何打破开发、测试与运维之间的沟通壁垒
在DevOps实践中,看板工具通过可视化任务管理和自动化流程,提升开发与运维团队的协作效率。它支持敏捷开发、持续交付,助力团队高效应对需求变化,实现跨职能协作与流程优化。
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
1760 8
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
2770 0