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

相关文章
|
11月前
|
数据可视化 Java BI
将 Spring 微服务与 BI 工具集成:最佳实践
本文探讨了 Spring 微服务与商业智能(BI)工具集成的潜力与实践。随着微服务架构和数据分析需求的增长,Spring Boot 和 Spring Cloud 提供了构建可扩展、弹性服务的框架,而 BI 工具则增强了数据可视化与实时分析能力。文章介绍了 Spring 微服务的核心概念、BI 工具在企业中的作用,并深入分析了两者集成带来的优势,如实时数据处理、个性化报告、数据聚合与安全保障。同时,文中还总结了集成过程中的最佳实践,包括事件驱动架构、集中配置管理、数据安全控制、模块化设计与持续优化策略,旨在帮助企业构建高效、智能的数据驱动系统。
504 1
将 Spring 微服务与 BI 工具集成:最佳实践
|
10月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1454 2
Spring Boot 3.x 微服务架构实战指南
|
10月前
|
负载均衡 Java API
《深入理解Spring》Spring Cloud 构建分布式系统的微服务全家桶
Spring Cloud为微服务架构提供一站式解决方案,涵盖服务注册、配置管理、负载均衡、熔断限流等核心功能,助力开发者构建高可用、易扩展的分布式系统,并持续向云原生演进。
|
11月前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
646 1
|
SpringCloudAlibaba API 开发者
新版-SpringCloud+SpringCloud Alibaba
新版-SpringCloud+SpringCloud Alibaba
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
666 1
|
负载均衡 Dubbo Java
Spring Cloud Alibaba与Spring Cloud区别和联系?
Spring Cloud Alibaba与Spring Cloud区别和联系?
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
3475 13
Spring Cloud Alibaba:一站式微服务解决方案
|
SpringCloudAlibaba 负载均衡 Dubbo
【SpringCloud Alibaba系列】Dubbo高级特性篇
本章我们介绍Dubbo的常用高级特性,包括序列化、地址缓存、超时与重试机制、多版本、负载均衡。集群容错、服务降级等。
2136 7
【SpringCloud Alibaba系列】Dubbo高级特性篇
|
人工智能 SpringCloudAlibaba 自然语言处理
SpringCloud Alibaba AI整合DeepSeek落地AI项目实战
在现代软件开发领域,微服务架构因其灵活性、可扩展性和模块化特性而受到广泛欢迎。微服务架构通过将大型应用程序拆分为多个小型、独立的服务,每个服务运行在其独立的进程中,服务与服务间通过轻量级通信机制(通常是HTTP API)进行通信。这种架构模式有助于提升系统的可维护性、可扩展性和开发效率。
5747 2