【Springcloud篇】学习笔记十(十七章):Sentinel实现熔断与限流——Hystrix升级

第十七章_Sentinel实现熔断与限流

1.Sentinel介绍

1.1是什么

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。 ==Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护==等多个维度保护服务的稳定性。

用来代替Hystrix

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • **完备的实时监控:**Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • **广泛的开源生态:**Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • **完善的 SPI 扩展点:**Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 的主要特性:

image-20230928194355871

1.2Hystrix与Sentinel比较

Hystrix:

  1. 需要我们程序员自己手工搭建监控平台
  2. 没有一套web界面可以给我们进行更加细粒度化得配置流控、速率控制、服务熔断、服务降级

Sentinel:

  1. 单独一个组件,可以独立出来。
  2. 直接界面化的细粒度统一配置。

约定 > 配置 > 编码

都可以写在代码里面,但是我们本次还是大规模的学习使用配置和注解的方式,尽量少写代码

2.Sentinel下载安装运行

官方文档:Spring Cloud Alibaba Reference Documentation (spring-cloud-alibaba-group.github.io)

服务使用中的各种问题:

  • 服务雪崩
  • 服务降级
  • 服务熔断
  • 服务限流

Sentinel 分为两个部分:

  • ==核心库(Java 客户端)==不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • ==控制台(Dashboard)==基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

2.1安装步骤

(1)下载

地址:

image-20230928194741667

(2)运行命令

前提:java8环境OK + 8080端口不能被占用

运行命令:

java -jar sentinel-dashboard-1.7.1.jar
(3)访问sentinel管理界面

image-20230928195028856

3.初始化演示工程

3.1新建cloudalibaba-sentinel-service8401

(1)pom
<dependencies>
        <!--         后续做Sentinel的持久化会用到的依赖-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- springcloud alibaba nacos 依赖,Nacos Server 服务注册中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- springboot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
 
        <!-- 日常通用jar包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
 
    </dependencies>
(2)yml

image-20230928195400596

(3)主启动

image-20230928200302156

(4)controller层

image-20230928200314254

(5)测试

启动成功之后,Sentinel控制台空空如也

原因:Sentinel采用懒加载,执行一次即可

localhost:8401/testB

image-20230928200131647

4.流控规则

4.1基本介绍

image-20230928202743895

(1)解释说明—重要
  • 资源名:唯一名称,默认请求路径
  • 针对来源:sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
  • 阈值类型/单机值:
    • QPS(每秒钟的请求数量):当调用该api就QPS达到阈值的时候,进行限流
    • 线程数.当调用该api的线程数达到阈值的时候,进行限流
  • 是否集群:不需要集群
  • 流控模式:
    • 直接:api达到限流条件时,直接限流。分为QPS和线程数
    • 关联:当关联的资源达到阈值时,就限流自己
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【api级别的针对来源】
  • 流控效果:
    • 快速失败:直接抛异常
    • warm up:根据codeFactor(冷加载因子,默认3)的值,从阈值codeFactor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效
(2)QPS和线程数的区别
  • QPS 类似于银行的保安:所有的请求到Sentinel 后,他会根据阈值放行,超过报错
  • 线程数类似于银行的窗口:所有的请求会被放进来,但如果阈值设置为1,那么其他的请求就会报错也就是,银行里只有一个窗口,一个人在办理业务中,其他人跑过来则会告诉你“现在不行,没到你”

image-20230928203107085

(3)重要属性

image-20230928203203875

4.2流控模式

(1)直接—默认
  • 配置及说明:表示1秒钟内查询1次就是OK,若超过次数1,就直接-快速失败,报默认错误

image-20230928203357449

测试:快速点击访问:http://localhost:8401/testA

image-20230928203452364

(2)关联
  • 解释:关联的资源达到阈值时,就限流自己

  • 配置及说明:当关联资源/testB的qps阀值超过1时,就限流/testA的Rest访问地址,

image-20230928203633810

使用postman新建多线程集合组:

image-20230928211352080

image-20230928211929131

运行后发现testA挂了,点击访问:http://localhost:8401/testA

image-20230928212018846

(3)链路

只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)【API级别的针对来源】

4.3流控效果

(1)快速失败

直接失败,抛出异常:Blocked by Sentinel (flow limiting)

(2)预热

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考 流量控制 - Warm Up 文档,具体的例子可以参见 WarmUpFlowDemo

通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:

image-20230928212921158

(3)WarmUp配置

默认 coldFactor 为 3,即请求QPS从(阈值 / 3) 开始,经多少预热时长才逐渐升至设定的 QPS 阈值

系统配置系统初始化的阀值为10 / 3 约等于3,即阀值刚开始为3;然后==过了5秒后阀值才慢慢升高恢复到10==。效果为:开始访问 localhost:/testA 时每秒请求别超过10/3个才能正常访问,5秒后可以接受的请求可以达到每秒10次。
image-20230928213139121

  • 应用场景

秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值

(4)排队等待

匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效

设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒

image-20230928213419344

说明:匀速排队,阈值必须设置为QPS

匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考流量控制 - 匀速器模式 ,具体的例子可以参见 PaceFlowDemo。

5.降级规则

5.1熔断降级概述

除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。

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

5.2降级策略介绍

image-20230928214232875

  • RT(平均响应时间,秒级)

    • 平均响应时间超出阈值在时间窗口内通过的请求>=5,两个条件同时满足后触发降级

    • 窗口期过后关闭断路器

    • RT最大4900(更大的需要通过-Dcsp.sentinel.statistic.max.rt=XXXX才能生效)

  • 异常比列(秒级)

    • QPS >= 5异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级
  • 异常数**(分钟级)**

    • 异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级

5.3RT

(1)介绍

平均响应时间(DEGRADE_GRADE_RT):当1s内持续进入5个请求,对应时刻的平均响应时间(秒级)均超过阈值( count,以ms为单位),那么在接下的时间窗口(DegradeRule中的timeWindow,以s为单位)之内,对这个方法的调用都会自动地熔断(抛出DegradeException )。注意Sentinel 默认统计的RT上限是4900 ms,超出此阈值的都会算作4900ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置。

  • 注意:Sentinel 1.7.0才有平均响应时间DEGRADE_GRADE_RT),Sentinel 1.8.0的没有这项,取而代之的是慢调用比例 (SLOW_REQUEST_RATIO)。

  • 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。熔断降级 · alibaba/Sentinel Wiki · GitHub

如图为Sentinel1.7.0的降级规则为RT策略流程图

image-20230928214849974

(2)实操

在controller中加入textD

image-20230928214948134

配置:当1s内持续进入5个请求(默认5个请求),对应时刻的平均响应时间(秒级)均超过0.2s( count,以ms为单位),那么在接下的时间窗口1s之内,对这个方法的调用都会自动地熔断

image-20230928222641033

  • Jmeter压测:永远一秒钟打进来10个线程(大于5个)调用testD

image-20230928222752474

image-20230928222448334

测试

image-20230928215233969

5.4异常比例

(1)介绍

异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= 5,并且==每秒异常总数占通过量的比值超过阈值( DegradeRule中的 count)==之后,资源进入降级状态,即在接下的时间窗口( DegradeRule 中的 timeWindow,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0, 1.0],代表0% -100%。

  • 注意:与Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半开状态),Sentinel 1.8.0的如下:

异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。熔断降级 · alibaba/Sentinel Wiki · GitHub

接下来讲解Sentinel 1.7.0

如图为Sentinel1.7.0的降级规则为异常比例策略流程图

image-20230928223524530

(2)实操

在controller中加入textE

image-20230928223839488

  • 配置说明:若满足1秒访问testE资源,并且有异常的访问次数超过百分之20的话,将进行服务降级,经过1秒的时间窗口之后,关闭服务降级

image-20230928223742528

  • 测试

    • 单独访问一次:localhost:8401/testE

      image-20230928224124166

    • Jmeter压测:

      image-20230928224336710

结论

按照上述配置,单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次;开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。

断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了

5.5异常数

(1)介绍

异常数( DEGRADE_GRADF_EXCEPTION_COUNT ):当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timeWindow小于60s,则结束熔断状态后可能再进入熔断状态。

说明:假设时间窗口期为10秒,设置的异常数不能超过5,统计阶段第1秒的时候有5个异常,服务熔断后进入时间窗口期,时间窗口期结束,但是一分钟还没结束,那么此时的异常数还是5个,又进入熔断状态。

注意,与Sentinel 1.8.0相比,有些不同(Sentinel 1.8.0才有的半开状态),Sentinel 1.8.0的如下:

异常数 (ERROR_COUNT):当单位统计时长(默认一分钟)内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

如图为Sentinel1.7.0的降级规则为异常数策略流程图

image-20230928225025284

由于异常数是按照分钟统计的,时间窗口一定要大于等于60秒

(2)实战

image-20230928225129953

  • 测试:连续5次之后

image-20230928225200462

6.热点key限流

6.1基本介绍

(1)热点介绍

何为热点:热点即经常访问的数据,很多时候我们==希望统计或者限制某个热点数据中访问频次最高的 Top N 数据,并对其访问进行限流==或者其它操作:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

image-20230929195345167

(2)兜底方法介绍

兜底方法,分为 系统默认 和 客户自定义 两种。

之前的案例,限流出问题后,都是用sentinel系统默认的提示: Blocked by Sentinel (flow limiting)

我们能不能自定?类似hystrix,某个方法出问题了,就找对应的兜底降级方法?

结论 - 从HystrixCommand到@SentinelResource

6.2实操

在controller中加入:

说明:@SentinelResource(value = “testHotKey”,blockHandler = “deal_testHotKey”)方法 testHotKey 里面第一个参数只要QPS超过每秒1次,马上降级处理,异常用了我们自己定义的兜底方法。

image-20230929195815865

配置说明:在1秒的窗口时间内,访问次数超过1的话,就开启限流

image-20230929201534489

  • 测试:快速点击,携带参数p1

  • 测试:快速点击,携带参数p2

    image-20230929201814037

6.3参数例外项

上述案例演示了第一个参数p1,当QPS超过1秒1次点击后马上被限流

特例情况:我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样

特例:假如当p1的值等于5时,它的阈值可以达到200

热点参数的注意点,参数必须是基本类型或者String

配置如下:

image-20230929202116636

  • 快速点击测试,当p1参数为5时候

image-20230929202206970

7.系统规则

7.1各项配置参数说明

image-20230929205240807

7.2@SentinelResource配置

pom文件增加:

		 <!-- 引入自己定义的api通用包,可以使用payment对象-->
        <dependency>
            <groupId>springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
(1)按自定义资源名称限流
①controller层
@RestController
public class RateLimitController {
    @GetMapping("/byResource")
    @SentinelResource(value = "byResource",blockHandler = "handleException")
    public CommonResult byResource(){
        return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
    }
    public CommonResult handleException(BlockException exception){
        return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
    }

}
②流控配置

image-20230930102439875

image-20230930102637564

③测试

快速点击测试:localhost:8401/byResource

image-20230930102659607

④额外问题

此时关闭服务8401,查看Sentinel控制台,流控规则消失,即为临时

image-20230930102826581

(2)按url地址限流
①controller层
    @GetMapping("/rateLimit/byUrl")
    public CommonResult byUrl(){
        return new CommonResult(200,"按url限流测试",new Payment(2020L,"serial002"));
    }
②流控配置

image-20230930103258198

image-20230930103318384

③测试

快速点击:localhost:8401/rateLimit/byUrl

image-20230930103342418

(3)上面兜底方案面临的问题
  • 系统默认的,没有体现我们自己的业务要求
  • 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观
  • 每个业务方法都添加一个兜底的,那代码膨胀加剧,局统一的处理方法没有体现
(4)客户自定义限流处理逻辑
①自定义限流处理逻辑CustomerBlockHandler
public class CustomerBlockHandler {
    public static CommonResult handlerException1(BlockException exception){
        return new CommonResult(4444,"按用户自定义,global handlerException.......1");
    }
    public static CommonResult handlerException2(BlockException exception){
        return new CommonResult(4444,"按用户自定义,global handlerException.......2");
    }
}
②controller层
//根据用户自定义流控规则进行限流,且实现全局流控规则
    @GetMapping("/rateLimit/customerBlockHandler")
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2")
    public CommonResult customerBlockHandler(){
        return new CommonResult(200,"按用户自定义",new Payment(2020L,"serial003"));
    }
③配置

注意:两个配置不能同时生效

image-20230930104018539

按自定义资源名流控

image-20230930104104198

按url地址流控

image-20230930104031998

④测试
按自定义资源名称流控配置

image-20230930104210359

按url地址流控配置

image-20230930104243564

⑤结论

在设置了 URL地址流控的前提下,设置按资源名称流控无效

即:URL地址流控优先级大于资源名称流控

7.3更多注解属性说明

image-20230930104414641

8.服务熔断功能

sentinel整合ribbon+spenFeign+fallback

8.1新建实验环境

(1)Ribbon系列-服务提供者9003/9004

启动nacos和sentinel,新建cloudalibaba-provider-payment9003/9004两个服务提供者

①pom
<dependencies>
        <!-- springcloud alibaba nacos 依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
 
        <!-- springboot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
 
        <!-- 日常通用jar包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
②yml

image-20230930114443389

③主启动

image-20230930114529734

④controller层

image-20230930114550602

(2)Ribbon系列-消费者84

新建cloudalibaba-consumer-nacos-order84

①pom
 <dependencies>
        <!-- 后续做Sentinel的持久化会用到的依赖 -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!-- sentinel  -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- springcloud alibaba nacos 依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- springboot整合Web组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
 
        <!-- 日常通用jar包 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
②yml

image-20231001100913661

③主启动

image-20230930115143290

④配置类

image-20230930115119145

⑤controller层
(3)针对消费者84有无配置fallback和blockHandler
①无配置

image-20231001102152987

  • 测试

    • 测试id为4

      image-20231001102253250

    • 测试id为5

      image-20231001102338157

②配置fallback

image-20231001102537471

image-20231001102550589

③配置blockHandler

image-20231001102838831

  • sentinel新增服务降级规则,是服务降级、是服务降级

    image-20231001103055161

    若一分钟内异常数超过2,则开启断路器,在80秒的时间窗口内,使用自定义的兜底方法,80秒一过,恢复默认的异常报错页面

    image-20231001103311516

  • 测试

image-20231001103440027

④同时配置fallback和blockHandler

image-20231001103912588

image-20231001104241525

  • 测试:

    • 第一、二次访问异常路径,显示的是配置fallback的兜底方法

      image-20231001104038066

    • 第三次访问异常路径,显示的是配置blockHandler的方法

      image-20231001104259597

8.2忽略异常

  • 84服务消费者的controller层

image-20231001104622498

  • 测试

    image-20231001104710464

    image-20231001104723843

9.sentinel整合feign

9.1步骤

(1)pom
	<!-- sentinel整合openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
(2)yml

image-20231001105611690

(3)主启动

主启动激活feign

image-20231001113115291

(4)feign指定寻找的服务

image-20231001113523121

(5)controller层

image-20231001113626818

(6)测试
  • 测试一

image-20231001113949765

  • 测试二:模拟feign调用远程服务超时(feign默认1秒)

9003和9004服务提供者controller新增:

image-20231001114121143

测试时发现如果只给一个微服务加延时,另一个不加,会一直调用没有延时的微服务,所以要么两个都加延时或者停掉一个

测试结果:服务降级

image-20231001114334110

10.Sentinel持久化

目前的sentinel 当重启以后,数据都会丢失,和 nacos 类似原理。需要持久化。它可以==被持久化到 nacos 的数据库中。==

10.1步骤

(1)pom
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
(2)yml

image-20231001114742137

(3)nacos新增配置

image-20231001115009756

resource:资源名称
limitApp:来源应用
grade:阈值类型,0表示线程数,1表示QPS,
count:单机阈值,
strategy:流控模式,0表示直接,1表示关联,2表示链路
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
cIusterM0de是否集群

总结: 就是在 sentinel 启动的时候,去 nacos 上读取相关规则配置信息,实际上它规则的持久化,就是第三步,粘贴到nacos上保存下来,就算以后在 sentinel 上面修改了,重启应用以后也是无效。

(4)测试

快速点击:

image-20231001115522282

  • 查看规则

image-20231001115551658

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/368001.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Web路由列表

什么是Web路由列表 在Web开发中&#xff0c;路由列表通常用于将请求的URL映射到相应的处理函数。尽管路由列表可以用不同的数据结构来实现&#xff0c;但在很多情况下是一个字典&#xff08;在Python中&#xff09;或其他类似的键值对结构。 路由列表&#xff08;Django&#…

远程手机搭建Termux环境,并通过ssh连接Termux

背景 Termux只能通过鼠标点击&#xff0c;无法使用电脑键盘&#xff0c;输入速度很慢&#xff0c;你想通过ssh 连接Termux&#xff0c;获得友好体验搞了个云手机&#xff0c;想像普通手机那样充当服务器想把自己的手机公开到局域网中供同事调试想把自己的模拟器公开到局域网中…

vue3-逻辑复用

什么是组合式函数 _无状态逻辑的函数_&#xff1a;它在接收一些输入后立刻返回所期望的输出。 比如 时间格式化的函数。 有状态逻辑的函数: 有状态逻辑负责管理会随时间而变化的状态。 比如 跟踪当前鼠标在页面中的位置。 在 Vue 应用的概念中&#xff0c;“组合式函数”(…

爬虫学习笔记-scrapy安装及第一个项目创建问题及解决措施

1.安装scrapy pycharm终端运行 pip install scrapy -i https://pypi.douban.com/simple 2.终端运行scrapy startproject scrapy_baidu,创建项目 问题1:lxml版本低导致无法找到 解决措施:更新或者重新安装lxml 3.项目创建成功 4.终端cd到项目的spiders文件夹下,cd scra…

JS 引导动画

前言 引导动画是程序在某一时刻播放的动画&#xff0c;通常用于向用户介绍程序的功能和特点。 实现效果 实现方式 引导动画的实现方式有很多种&#xff0c;这里我使用的是 CSS 的 clip-path 属性。 技术选型 这里我为什么要选择 clip-path 属性而不是 mask 属性呢&#xf…

SpringbootWeb案例

准备工作 需求说明 部门管理 部门管理功能开发包括&#xff1a;查询部门列表、删除部门、新增部门、修改部门   员工管理功能开发包括&#xff1a;查询员工列表(分页、条件)、删除员工、新增员工、修改员工 环境搭建 环境搭建步骤&#xff1a;1. 准备数据库表(dept、emp)…

ubuntu 安装 kvmQemu no active connection to install on

更新 apt sudo apt update检查虚拟化是否开启 0 不开&#xff0c;其余数字表示开启&#xff0c;开不开都可以&#xff0c;不开性能弱&#xff0c;只能跑 x86 系统 egrep -c (vmx|svm) /proc/cpuinfo安装 sudo apt install -y qemu-kvm virt-manager libvirt-daemon-system virt…

2.3作业

写一个shell脚本判断用户输入的是否是数字

我要成为嵌入式高手之2月3日Linux高编第一天!!

学习框架 一、IO编程 多任务编程&#xff08;进程、线程&#xff09; 网络编程 数据库编程 二、数据结构 学习笔记 Linux软件编程&#xff1a; 一. Linux 1、Linux: 操作系统的内核&#xff0c;真正的操作系统叫Ubuntu、Redhat、CentOS..... 内核&#xff08;纯c实现的代码…

pdmodel从动态模型转成静态onnx

1.下载项目 git clone https://github.com/jiangjiajun/PaddleUtils.git 2.新建两个新的文件夹 第一个文件夹放两个必要文件 第二个文件夹可以设置为空&#xff0c;用来存放转换后的模型 如图&#xff1a; 3.在终端运行 python paddle/paddle_infer_shape.py --model_dir …

DevOps落地笔记-10|环境管理:交付测试环境的迅猛方法

上一讲我主要介绍在开发过程中如何处理应用程序在不同环境的配置问题&#xff0c;通过有效管理应用程序的配置&#xff0c;最终实现一包到底。不同的环境不仅会带来应用程序本身的配置管理问题&#xff0c;环境本身的创建、管理、一致性等问题也需要解决。环境管理的问题也是我…

在jetbrains IDEA/Pycharm/Android Studio中安装官方rust插件,开始rust编程

在idea插件市场搜索rust&#xff1a;JetBrains Marketplace &#xff0c;就可以找到rust插件&#xff1a; jetbrains官方rust插件地址&#xff1a;[Deprecated] Rust - IntelliJ IDEs Plugin | Marketplace 直接在idea中搜索rust好像是搜不到的&#xff1a; 需要在这个插件市场…

Nginx简单阐述及安装配置

目录 一.什么是Nginx 二.Nginx优缺点 1.优点 2.缺点 三.正向代理与反向代理 1.正向代理 2.反向代理 四.安装配置 1.添加Nginx官方yum源 2.使用yum安装Nginx 3.配置防火墙 4.启动后效果 一.什么是Nginx Nginx&#xff08;“engine x”&#xff09;是一个高性能的HTTP…

Python3 交叉编译 numpy pandas scipy scikit-learn

1. 概述 由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件&#xff0c;如果是arm64位的系统&#xff0c;很多包都有预编译好的版本&#xff0c;可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)环境下交叉编译。 2. 编译环境搭建 创建…

自编C++题目——水龙头

预估难度 简单 题目描述 有个水龙头&#xff0c;其中有一些坏了的&#xff08;用表示&#xff09;&#xff0c;还有一些能用的&#xff08;用表示&#xff09;&#xff0c;那么有多少个能用的&#xff1f; 输入格式 第一行&#xff1a;整数&#xff0c;表示水龙头的个数&a…

SpringBoot 解决 getReader() has already been called for this request

一、getReader()问题分析 1、获取请求参数的方式 对于 GET 请求和 POST 表单请求&#xff0c;参数都是包含在 URL 查询字符串中的&#xff0c;因此在拦截器中都可以通过使用 request.getParameter(“paramName”)来获取这些参数。 对于 POST JSON 请求&#xff0c;参数通常包…

【Vue】mvc,mvp,mvvm 的区别

总结&#xff1a; MVC : view 视图层依靠 model 来进行更新渲染&#xff0c;当数据发生改变时。第一步: 通知 controller 进行更新&#xff0c;然后第二步 controller 再通知 model 进行更新。最后 model 才将 view 更新 , 这样大量的逻辑以及更新操作&#xff0c;都需要在con…

2024.2.3每日一题

LeetCode 石子游戏 VII 1690. 石子游戏 VII - 力扣&#xff08;LeetCode&#xff09; 题目描述 石子游戏中&#xff0c;爱丽丝和鲍勃轮流进行自己的回合&#xff0c;爱丽丝先开始 。 有 n 块石子排成一排。每个玩家的回合中&#xff0c;可以从行中 移除 最左边的石头或最右…

【已更新】2024美赛C题代码教学思路数据处理数学建模分析Momentum in Tennis

问题一完整的代码已给出&#xff0c;预计2号晚上或者3号凌晨全部给出。 代码逻辑如下&#xff1a; C题第一问要求我们开发一个模型&#xff0c;捕捉得分时的比赛流程&#xff0c;并将其应用于一场或多场比赛。你的模型应该确定哪名球员在比赛的特定时间表现得更好&#xff0c;…

C系列-动态内存管理

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” 目录 为什么要有动态内存分配 malloc和free malloc free calloc和realloc calloc realloc 常见的动态内存的错误 对NULL指针的解引用操作 ​编辑 对动态开辟空间的越界访问…