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控制台



相关文章
|
25天前
|
测试技术 持续交付 UED
软件测试的艺术:确保质量的实战策略
在软件开发的舞台上,测试是那把确保每个功能如交响乐般和谐奏响的指挥棒。本文将深入探讨软件测试的重要性、基本类型以及如何设计高效的测试策略。我们将通过一个实际的代码示例,展示如何运用这些策略来提升软件质量和用户体验。
|
19天前
|
Java 测试技术 API
详解Swagger:Spring Boot中的API文档生成与测试工具
详解Swagger:Spring Boot中的API文档生成与测试工具
32 4
|
1月前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
58 3
|
1月前
|
缓存 测试技术 Apache
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
告别卡顿!Python性能测试实战教程,JMeter&Locust带你秒懂性能优化💡
52 1
|
1月前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
57 2
|
1月前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
40 2
|
20天前
|
Java 测试技术 数据库连接
使用Spring Boot编写测试用例:实践与最佳实践
使用Spring Boot编写测试用例:实践与最佳实践
47 0
|
Java 数据库 数据安全/隐私保护
《Spring 3.0就这么简单》——1.2 实例功能概述
Spring拥有持久层、业务层和展现层的“原生技术”,分别是Spring JDBC、声明式事务和Spring MVC。为了充分展现Spring本身的魅力,在本章中仅使用Spring的这些原生技术,在以后的章节中,我们将学习其他的持久层和展现层技术,只要用户愿意,就可以平滑地将其过渡到其他技术实现中。
2097 0
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
216 2
|
23天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
39 1
SpringBoot入门(7)- 配置热部署devtools工具