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

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

一. Sentinel概念

1. 什么是Sentinel?

Sentinel是阿里中间件团队研发面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。于2012年诞生,后续在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景,Sentinel也因此积累了大量的流量归整场景及生产实践。最终在2018年7月宣布对外界开源。


Sentinel的基本概念:


资源: Sentinel 的关键概念,可以是Java应用程序中任何内容,通过Sentinel API定义的代码,能够被Sentinel保护起来,大部份情况下,可以使用方法签名,URL,甚至服务名称作为资源名

**规则:**围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

Sentinel分为两个部分:


控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器,也就是sentinel-dashboard-1.8.1.jar。

核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

2. Sentinel功能特性


微信图片_20230710073852.png

从上图可知Sentinel的功能特性很多以及应用场景非常广泛,以下就限流、熔断降级这几个常见的功能特性以及意义进行简要说明


**限流:**限流同时也叫做流量控制,原理是监控应用流量的QPS或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。


微信图片_20230710073900.gif


**熔断降级:**除了流量控制以外,及时对调用链路中的不稳定因素进行熔断也是Sentinel的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积,进而导致级联错误。Sentinel当检测到调用链路中某个资源出现不稳定的表现(请求响应时间长或异常比例升高),则对这个资源的调用进行限制,让请求快速失败,避免影响到其他资源而导致级联故障。


熔断: 拒绝流量访问,当系统恢复正常时关闭熔断。

**降级:**将次要服务降级,停止服务,将系统资源放出来给核心功能

微信图片_20230710073905.png


3. Sentinel VS Hystrix

以下摘自Sentinel官方文档,详情点击 Sentinel 与 Hystrix 的对比


Sentinel Hystrix

隔离策略         信号量隔离                 线程池隔离/信号量隔离

熔断降级策略     基于响应时间或失败比率       基于失败比率

实时指标实现        滑动窗口·                 滑动窗口(基于 RxJava)

规则配置           支持多种数据源              支持多种数据源

扩展性           多个扩展点                           插件的形式

基于注解的支持 支持                              支持

限流    基于 QPS,支持基于调用关系的限流 有限的支持

流量整形 支持慢启动、匀速器模式 不支持

系统负载保护 支持 不支持

控制台 开箱即用,可配置规则、查看秒级监控、机器发现等 不完善

常见框架的适配 Servlet、Spring Cloud、Dubbo、gRPC 等 Servlet、Spring Cloud Netflix

Sentinel 和 Hystrix 的原则是一致的,但是在限制手段上,Sentinel和Hystrix采取了完全不一样的方法。


Hystrix: 通过线程池隔离,来对依赖(在Sentinel的概念对应资源)进行了隔离。好处在于资源之间做到最彻底的隔离,缺点是除了增加了线程切换的成本,还需要预先给各个资源做线程池大小的分配。

Sentinel : 通过并发线程数进行限制和响应时间对资源进行降级两种手段。

二. Docker部署Sentinel Dashboard

1. 拉取镜像

docker pull bladex/sentinel-dashboard


2. 启动容器

docker run --name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard


3. 访问测试

访问:http://IP:8858


用户名/密码:sentinel/sentinel

微信图片_20230710073937.png



三. Sentinel网关流控

1. 网关流控定义

Sentinel支持对Spring Cloud Gateway、Zuul等主流的API Gataway 进行限流,作用在网关的流控称之为网关流控,其实现原理请点击网关限流进入官方Wiki查看。


这里只把原理图从官方文档摘出来,需多关注图中提到的模块名和几个类名,因为都是核心级别的存在。

微信图片_20230710073949.png



规则类型gw-flow和gw-api-group为网关流控规则,具体类型请查看规则类型枚举RuleType


/**

* flow 流控规则

*/

FLOW("flow", FlowRule.class),

/**

* degrade 降级规则

*/

DEGRADE("degrade", DegradeRule.class),

/**

* param flow 热点规则

*/

PARAM_FLOW("param-flow", ParamFlowRule.class),

/**

* system 系统规则

*/

SYSTEM("system", SystemRule.class),

/**

* authority 授权规则

*/

AUTHORITY("authority", AuthorityRule.class),

/**

* gateway flow 网关限流规则

*/

GW_FLOW("gw-flow","com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),

/**

* api 用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合

*/

GW_API_GROUP("gw-api-group","com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");


微信图片_20230710073953.png


2. 网关流控规则

Field

说明

默认值

resource

网关route或自定义API分组名称(注:网关route这里的值不是route.id,可调试


resourceMode


网关route

grade

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

QPS

count

限流阈值,QPS阈值或线程数值


intervalSec

统计时间间隔

1秒

controlBehavior

流控效果,目前支持快速失败【0】和匀速排队【1】

快速失败

burst

应对突发请求时额外允许的请求数目


maxQueueingTimeoutMs

匀速排队模式下的最长排队时间,单位毫秒,仅在匀速排队模式下生效


paramItem

参数属性配置,parseStrategy:提取参数策略(0:Clien IP,1:Remote HOST,2:Header,3:请求参数,4:Cookie);fieldName:若提取策略是Header模式或者URL参数模式,则需要指定header名称或URL参数名称;pattern:参数值的匹配模式;matchStrategy:参数值的匹配策略,支持精确匹配,子串匹配和正则匹配。


Field 说明 默认值

resource 资源名称,网关route或自定义API分组名称(注:网关route这里的值不是route.id,可调试

resourceMode 限流资源类型,网关route【0】或自定义API分组【1】(详细查看GatewayFlowRule和SentinelGatewayConstants) 网关route

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

count 限流阈值,QPS阈值或线程数值

intervalSec 统计时间间隔,单位秒 1秒

controlBehavior 流控效果,目前支持快速失败【0】和匀速排队【1】 快速失败

burst 应对突发请求时额外允许的请求数目

maxQueueingTimeoutMs 匀速排队模式下的最长排队时间,单位毫秒,仅在匀速排队模式下生效

paramItem 参数属性配置,parseStrategy:提取参数策略(0:Clien IP,1:Remote HOST,2:Header,3:请求参数,4:Cookie);fieldName:若提取策略是Header模式或者URL参数模式,则需要指定header名称或URL参数名称;pattern:参数值的匹配模式;matchStrategy:参数值的匹配策略,支持精确匹配,子串匹配和正则匹配。

3. 导入依赖

com.alibaba.cloud

spring-cloud-alibaba-sentinel-gateway


com.alibaba.cloud

spring-cloud-starter-alibaba-sentinel


com.alibaba.csp

sentinel-datasource-nacos



4. 网关配置

先放在本地Spring Boot配置文件bootstrap-dev.yml中,后面测试通过把后再把Sentinel配置放至Nacos


spring:

 cloud:

   nacos:

     # 注册中心

     discovery:

       server-addr: http://localhost:8848

     # 配置中心

     config:

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

       file-extension: yaml

   sentinel:

     enabled: true # sentinel开关

     eager: true

     transport:

       dashboard: 192.168.1.188:8858

       client-ip: localhost

     datasource:

       # 网关限流规则,gw-flow为key,随便定义

       gw-flow:

         nacos:

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

           dataId: ${spring.application.name}-gw-flow-rules # 流控规则配置文件名:youlai-gateway-gw-flow-rules

           groupId: SENTINEL_GROUP

           data-type: json

           rule-type: gw-flow

       # 自定义API分组,gw-api-group为key,随便定义

       gw-api-group:

         nacos:

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

           dataId: ${spring.application.name}-gw-api-group-rules # 流控规则配置文件名:youlai-gateway-gw-api-group-rules

           groupId: SENTINEL_GROUP

           data-type: json

           rule-type: gw-api-group


这里解释下配置中的datasource,因为在Sentinel添加流控规则之后,如果重启服务,之前配置的规则就会消失,所以这里需要持久化Sentinel配置,从上面的配置可以看出选择的是Nacos。不过这里先别急在Nacos添加网关流控规则,下文在测试确认需求后配置。


5. 网关流控客户端标识

网关流控和普通流控有很多区别,其中网关流控类型是gw-flow,普通流控类型是flow


怎么标识流控是网关类型呢?


很多博客文章都没有着重此点,因为前阵子纠结于网关流控的面板和普通流控的面板不一致而去搜相关的资料,最后还是在Sentinel官方文档中找到此开关,就是需要在youlai-gateway网关应用添加JVM启动参数。


# 注:通过 Spring Cloud Alibaba Sentinel 自动接入的 API Gateway 整合则无需此参数

-Dcsp.sentinel.app.type=1

1

2

具体如下图:


微信图片_20230710074017.png


6. 测试需求制定

在做好上面Sentinel Dashboard部署以及Spring Cloud Gateway整合Sentinel工作之后,Sentinel的两个部分(控制台和Java客户端)也就齐活了,那么接下来就进入测试。


下图简单的描述了OAuth2认证接口的流程,用户请求网关,网关(youlai-gateway)根据请求标识转发至认证中心,认证中心(youlai-auth)需要从系统服务(youlai-admin)获取数据库的用户信息再和请求携带的用户信息进行密码判读,成功则返回token给用户。



微信图片_20230710074020.png

针对以上的OAuth2认证流程,提出来一个需求:


假设认证中心服务的QPS上限为10,系统服务的QPS上限为5,如何通过Sentinel实现限流控制?


**温馨提示:**留意下上图中的红线部分,你认为网关的流控是否能限制到与其间接相关的系统服务youlai-admin吗?


7. Nacos添加网关流控规则

进入Nacos控制台,添加网关流控规则,具体内容参考网关流控字段说明。


需要注意的是资源名称resource不是路由中配置的route的id,在开启Sentinel时调试SentinelGatewayFilter#filter方法可以看到自动生成的是固定前缀ReactiveCompositeDiscoveryClient_拼接应用名称${spring.application.name},所以在配置文件中一定要按照自动生成的规则配置resource的值。填写网关路由route的id,Sentinel的网关流控是无法生效的。


微信图片_20230710074023.png


上面网关流控规则中,限制了认证中心youlai-auth的QPS上限为10,系统服务youlai-admin的QPS上限为5。


至于为什么这么设定,因为有个猜想需要验证,网关流控是否只能限制和直接关联的youlai-auth,而不能限制间接相关的youlai-admin。


如果通过的QPS是10,那说明网关流控不能控制间接相关youlai-admin,如果通过的QPS是5,则说明网关流控能控制间接相关的youlai-admin,至于结果,先留个悬念吧,看下文的测试结果。


已添加的网关流控规则如下图:


微信图片_20230710074050.png


在Nacos添加了网关流控规则之后,会同步到Sentinel,进入Sentinel控制台查看

微信图片_20230710074053.png



8. 网关流控测试

在完成上述步骤之后,接下来就进入真正的测试环节。


添加线程组


测试计划(鼠标右击)->添加->线程(用户)->线程组


微信图片_20230710074109.png


因为youlai-auth的QPS处理上限为10,所以这里的线程数大于10即可看到被限制的请求

微信图片_20230710074119.png



添加HTTP请求


OAuth2登录线程组(鼠标右击)->添加->取样器->HTTP请求

微信图片_20230710074122.png



接口是通过网关转发到认证中心的认证接口获取token

微信图片_20230710074124.png



添加察看结果树


因为要看请求的响应,所以这里添加察看结果树。


OAuth2登录线程组(鼠标右击)->添加->监听器->察看结果树

微信图片_20230710074129.png



启动线程组测试


启动线程组,每秒15次认证请求,需要注意的是,如果测试计划有多个线程组,需禁用除了测试之外的其他线程组。

微信图片_20230710074131.png



点击察看结果树查看请求的情况

微信图片_20230710074134.png



进入Sentinel控制台,查看实时监控

微信图片_20230710074139.png



可以看到1秒15次请求,因为流控设置的QPS上限是10,所以10次通过,被Sentinel拒绝了5次。


这个结果也直接说明了网关流控并不是万能的,不能限制OAuth2认证请求中与其间接相关youlai-admin的微服务,因为在网关流控设置了youlai-admin的QPS上线为5,但最后整条链路成功的却是10。既然网关流控无法应对此类场景,是否还有其他的办法来做到呢?当然有:普通流控。


9. 自定义网关流控异常

上面Sentinel限流的默认异常响应如下


{"code":429,"message":"Blocked by Sentinel: ParamFlowException"}

1

假如想自定义网关流控异常响应,该如何实现呢?


可以通过在GatewayCallbackManager上通过setBlockHandler方法注册回调实现,当请求被限流后,实现自定义的异常响应。


微信图片_20230710074243.png


自定义异常代码:


@PostConstruct

private void initBlockHandler() {

   BlockRequestHandler blockRequestHandler = (exchange, t) ->

       ServerResponse.status(HttpStatus.OK)

       .contentType(MediaType.APPLICATION_JSON)

       .body(BodyInserters.fromValue(ResultCode.FLOW_LIMITING.toString()));

   GatewayCallbackManager.setBlockHandler(blockRequestHandler);

}


JMeter中查看被限流的响应,可以看到已按照自定义的响应异常返回,其中B0210 是Java开发手册上的关于系统限流的错误码

微信图片_20230710074247.png

相关文章
|
3月前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
83 1
|
1月前
|
运维
【运维基础知识】用dos批处理批量替换文件中的某个字符串(本地单元测试通过,部分功能有待优化,欢迎指正)
该脚本用于将C盘test目录下所有以t开头的txt文件中的字符串“123”批量替换为“abc”。通过创建批处理文件并运行,可实现自动化文本替换,适合初学者学习批处理脚本的基础操作与逻辑控制。
134 56
|
1月前
|
测试技术
Appscan手工探索、手工测试功能实战
Appscan手工探索、手工测试功能实战
|
2月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
247 3
快速上手|HTTP 接口功能自动化测试
|
2月前
|
Java 数据中心 Sentinel
spring boot sentinel 的使用
要实现Spring Boot集成Sentinel的熔断降级,需引入Sentinel依赖并配置Dashboard地址;使用`@SentinelResource`注解定义受保护资源及blockHandler处理降级逻辑;通过Sentinel Dashboard配置熔断规则,如异常比例或响应时间。启动应用后,测试熔断功能,确保Sentinel正常工作。建议动态调整规则以提升系统稳定性。
|
2月前
|
监控 Java API
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
先简单介绍熔断、降级等核心概念,然后阐述SpringBoot整合Sentinel的实现方式,最后介绍Sentinel在本项目中的应用。
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
|
3月前
|
XML Web App开发 数据挖掘
Postman接口测试工具全解析:功能、脚本编写及优缺点探讨
文章详细分析了Postman接口测试工具的功能、脚本编写、使用场景以及优缺点,强调了其在接口自动化测试中的强大能力,同时指出了其在性能分析方面的不足,并建议根据项目需求和个人偏好选择合适的接口测试工具。
111 1
|
3月前
|
缓存 算法 Java
非功能需求的测试
非功能需求的测试
39 2
|
3月前
|
Web App开发 敏捷开发 测试技术
自动化测试之美:使用Selenium WebDriver进行网页功能验证
【8月更文挑战第29天】在数字时代,软件质量是企业竞争力的关键。本文将深入探讨如何通过Selenium WebDriver实现自动化测试,确保网页应用的可靠性和性能。我们将从基础设置到编写测试用例,逐步引导读者掌握这一强大的测试工具,同时分享实战经验,让测试不再是开发的负担,而是质量保证的利器。
|
3月前
|
测试技术
一款功能完善的智能匹配1V1视频聊天App应该通过的测试CASE
文章列举了一系列针对1V1视频聊天App的测试用例,包括UI样式、权限请求、登录流程、匹配逻辑、消息处理、充值功能等多个方面的测试点,并标注了每个测试用例的执行状态,如通过(PASS)、失败(FAIL)或需要进一步处理(延期修改、待定、方案再定等)。
66 0