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

相关文章
|
2月前
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
59 1
|
2月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
20天前
|
监控 Java API
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
先简单介绍熔断、降级等核心概念,然后阐述SpringBoot整合Sentinel的实现方式,最后介绍Sentinel在本项目中的应用。
谷粒商城笔记+踩坑(25)——整合Sentinel实现流控和熔断降级
|
21天前
|
监控 Java Nacos
SpringCloud基础5——微服务保护、Sentinel
sentinel、雪崩问题、流量控制、隔离和降级、授权规则、规则持久化
SpringCloud基础5——微服务保护、Sentinel
|
21天前
|
JavaScript 前端开发 Java
Spring Boot+cucumber+契约测试
Spring Boot+cucumber+契约测试
11 0
Spring Boot+cucumber+契约测试
|
2月前
|
负载均衡 监控 Java
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
SpringCloud常见面试题(一):SpringCloud 5大组件,服务注册和发现,nacos与eureka区别,服务雪崩、服务熔断、服务降级,微服务监控
|
15天前
|
Java API 微服务
微服务保护之熔断降级
在微服务架构中,服务之间的调用是通过网络进行的,网络的不确定性和依赖服务的不可控性,可能导致某个服务出现异常或性能问题,进而引发整个系统的故障,这被称为 微服务雪崩。
14 0
|
2月前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
38 0
|
2月前
|
监控 供应链 安全
构建高效微服务架构:API网关与服务熔断策略
【7月更文挑战第38天】随着现代应用程序向微服务架构的转型,系统的稳定性和效率成为了开发团队关注的焦点。本文将探讨在微服务环境中实现系统可靠性的关键组件——API网关,以及如何在服务间通讯时采用熔断机制来防止故障蔓延。通过分析API网关的核心功能和设计原则,并结合熔断策略的最佳实践,我们旨在提供一套提高分布式系统弹性的策略。
|
3月前
|
监控 Dubbo 应用服务中间件
通用快照方案问题之Sentinel与SpringCloud和Dubbo的整合如何解决
通用快照方案问题之Sentinel与SpringCloud和Dubbo的整合如何解决
39 0
下一篇
无影云桌面