05-微服务Sentinel流量哨兵

一、Sentinel介绍

1.1 什么是Sentinel

  1. 分布式系统的流量防卫兵:随着微服务的普及,服务调用的稳定性变得越来越重要。Sentinel以“流量”为切入点,在流量控制、断路、负载保护等多个领域开展工作,保障服务可靠性。
  2. 特点:
      1. 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
      1. 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
      1. 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
    • 4.完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

1.2 Sentinel好处

分布式系统面临的问题:复杂的体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败,比如如下的例子中,当我们调用A、E、F、J、K这几个服务的时候如果其中一个服务出现问题会造成什么问题?其实就会出现整体系统效率全部下降,而且严重就会出现服务雪崩的问题!
image.png

1.2.1 服务雪崩

多个微服务之间调用的时候,假设A调用B和C,B和C又调用其他的微服务,这就是所谓的扇出。如果扇出的某个链路上某个微服务调用的响应时间过程或者不可用,微服务A的调用就用占用越来越多的系统资源,从而引起系统崩溃,这也就是服务雪崩。其实就是服务的高可用遭到了破坏。

对于高流量的应用来说,单一的后端依赖可能会导致服务器上的所有资源都在几秒钟内饱和。同时还有可能造成这些应用程序导致服务之间的延迟增加,备份列队,线程和其他的系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系失败,不能取消整个应用程序或系统,所以通常发生了一个模块的某个实例失败后,这时候这个模块依然还会接受流量,然后这个有问题的模块还调用其他的模块,这样就会发生级联故障,或者叫做雪崩

要解决这种问题的出现我们就需要用到服务降级,而Sentinel就可以保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,提高分布式系统的弹性。

1.2.2 Sentinel的熔断降级通过断路器实现

断路器:它本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似于熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法抛出的异常,这样就保证了服务调用方的不会被长时间、不必要的占用,从而避免了故障在分布式系统中蔓延(类似于病毒传染),从而避免了故障在系统中蔓延,乃至崩溃。

1.2.3 好处体现

对比与其他的产品而言,比如说Hystrix,他不需要我们自己手动搭建监控平台,而且它有一套类似于Nacos的Web界面,可以让我们进行更加细粒度的配置流控、速率、服务熔断、服务降级等

目前主流编程都是 约定>配置>代码,虽然我们的配置都可以写在代码中,但是我们还是要大面积的学习配置和注解的方式,尽量少些代码,这也是Sentinel的理念和初衷。
image.png

1.2.4 Sentinel的生态系统

image.png

二、Sentinel的下载安装

可以选择下载jar包,也可以下载源码包进行编译

下载地址:https://github.com/alibaba/Sentinel/releases

官方提供的手册:Spring Cloud 阿里巴巴参考文档 (spring-cloud-alibaba-group.github.io)

2.1 Sentinel 分为两个部分

  • 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。
  • 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等

2.2 启动Sentinel

注意:Sentinel控制台默认端口8080,保证8080端口不会被其他服务占用

  • 启动命令 java -jar sentinel-dashboard-1.8.7.jar
  • 访问地址 http://localhost:8080
  • 登录web页面 默认用户名/密码 sentinel/sentinel

首次访问web页面是空白的。因为sentinel默认是懒加载的方式,我们手动访问某个接口,web控制台就会出现信息。
image.png

image.png

三、初始化监控

3.1 搭建服务

  • 搭建cloud-sentinel-8042新的module
  • POM文件引入sentinel依赖
<!-- Nacos客户端依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- sentinel依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
  • 配置yml文件,保证8042服务能够注册到Nacos,然后被8080Sentinel控制台监控
server:  
  port: 8042  
spring:  
  application:  
    name: cloud-sentinel-8042  
  cloud:  
    nacos:  
      discovery:  
        server-addr: localhost:8848  
    sentinel:  
      transport:  
        # 配置Sentinel dashboard地址  
        dashboard: localhost:8080  
        # 默认8719端口,键入被占用会自动从8719+1,直到找到未被占用的端口  
        port: 8719  
      web-context-unify: false  
management:  
  endpoint:  
    web:  
      exposure:  
        include: '*'

3.2 启动8042服务

image.png

快速访问我们的接口,可以看到监控的曲线图效果,已经在监控
image.png

四、Sentinel流控规则

image.png

4.1 规则参数介绍

  • 资源名:唯一名称,默认请求路径
  • 针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
  • 阈值类型/单机阈值:
    • QPS(每秒钟的请求数量):当调用该API的QPS达到阈值的时候,进行限流
    • 线程数:当调用该API的线程数量达到阈值的时候,进行限流
  • 是否集群:当前不需要集群
  • 流控模式:
    • 直接:API达到限流条件时,直接限流
    • 关联:当关联的资源达到阈值时,就限流自己
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)(API级别的针对来源)
  • 流控效果:
    • 快速失败:直接失败,抛异常
    • Wam Up:根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFacotor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效

4.2 流控模式–直接–流控效果快速失败

4.2.1 QPS快速失败案例

  1. 针对/testA 接口设置QPS快速失败流控

解释:我们现在单机阈值设定为1,代表的是当前这个接口只能被1秒访问一次,超过这个阈值,就会被Sentinel阻塞,现在默认为直接失败,会在浏览器直接抛出异常

image.png

  1. 浏览器异常展示
    快速访问浏览器就会被Sentinel阻塞限流,如果一秒一次就不会被限流

image.png

4.2.2 线程数快速失败案例

QPS和并发线程数规则详解

image.png

让一个线程再进来办理的时候需要0.8秒,但是这个时候后面的线程也在疯狂的访问,所以后面的线程就会不会生效。

@GetMapping("/testA")  
public String testA(){  
  
    try {  
        TimeUnit.MILLISECONDS.sleep(800);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
    return "testA";  
}

image.png

通过开启两个访问窗口,快速切换实现两个线程同时访问,这时候直接阻塞限流
image.png
注意:这个时候虽然效果一致,但是是两种完全不同的规则,一种是QPS,一种是并发线程!

4.3 流控模式–关联–流控效果快速失败

当关联的资源达到阈值时,就限流自己。
比如拿我们的程序,现在有testA接口和testB接口,当A关联的资源B达到阈值后,就限流自己,也就是B到达阈值,限流A本身

当关联资源/testB的qps阈值超时1时,就限流/testA**的Rest访问地址,当关联资源到阈值后限制配置好的资源名

image.png

这时候我们利用postman工具,模拟20个线程间隔0.3毫秒去请求testB接口。
然后这时候我们在去浏览器访问testA 接口,此时就会限流
image.png

4.4 流控规则–链路–流控效果快速失败

链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流,它的功能有点类似于针对来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。

比如在一个微服务中,两个接口都调用了同一个Service中的方法,并且该方法用SentinelResource(用于定义资源)注解标注了,然后对该注解标注的资源(方法)进行配置,则可以选择链路模式。

image.png

4.4.1 具体演示代码

	@Service
public class TestService {
    // 定义限流资源
    @SentinelResource("common")
    public String common(){
        return "common";
    }
}

controller

@GetMapping("/testC")  
public String testC(){  
    return testService.common();  
}  
  
@GetMapping("/testD")  
public String testD(){  
    return testService.common();  
}

4.4.2 配置流控规则

这里要注意不要对/testA或者/testB进行限流规则的配置,要给用SentinelResource注解标注的资源进行配置限流规则,这里的意思为当我们用入口资源访问被SentinelResource注解标注的资源方法时,当超过阈值就会被限流。

image.png

通过浏览器访问testC 接口直接报错
image.png

4.5 流控模式–直接–流控效果预热(Warm Up)

4.5.1 预热解释

Warm Up方式,即预热/冷启动方式。该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。

预热公式:阈值/coldFactor(默认值为3),经过预热时间后才会达到阈值
冷启动的过程系统允许通过的QPS曲线如下图:
image.png
image.png

4.5.2 具体案例

默认coldFactor为3,当发起请求即请求QPS从(阈值/3)开始,经过多长预热时长才逐步升至设定的QPS阈值,当前阈值设置为10,预热时长设置为5秒。

设置流控规则
最终的效果,系统初始化时阈值/3约等于3,即阈值在此时为3,经过5秒后阈值才慢慢升高到10

image.png

直接访问浏览器刷新,可以看到Sentinel的实时监控
image.png

4.6 流控模式–直接–流控效果排队等待

4.6.1 排队等待介绍

匀速器RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式。这种方式严格控制了请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
image.png
这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

中心思想:

以固定的间隔时间让请求通过。当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值,则让当前请求通过。否则,计算当前请求的预期通过时间,如果该请求的预期通过时间小于规则预设的 timeout 时间,则该请求会等待直到预设时间到来通过(排队等待处理);若预期的通过时间超出最大排队时长,则直接拒接这个请求。
image.png

Sentinel 匀速排队等待策略是漏桶算法结合虚拟队列等待机制实现的。

注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

4.6.2 具体案例

image.png

可以通过压测工具模拟大量请求验证效果。10个请求匀速通过

image.png

五、熔断介绍

5.1 熔断降级

5.1.1 概述

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

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

5.2.2 熔断策略

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

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

  • 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
    ==注意异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException

熔断状态有三种状态,非别为OPEN、HALF_OPEN、CLOSED

状态说明
OPEN表示熔断开启,拒绝所有请求
HALF_OPEN探测恢复状态,如果接下来的一个请求顺利通过则表示结束熔断,否则继续熔断
CLOSE表示熔断关闭,请求顺利通过

5.2.3 熔断规则

熔断降级规则包含下面几个重要的属性:

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 引入)

官方文档网址:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html

5.2 熔断策略-慢调用比例

5.2.1 介绍

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

image.png

简单理解: 1QPS(1秒钟的请求) 比如说1秒钟请求了6次,大于设置的最小请求数(5),并且设置的最大响应时间大于设置的比例阈值,那么这个请求就会被熔断。接下来在设置的这个熔断时长的范围内,所有请求继续熔断。当过了熔断时长后,如果在来一个请求,响应时长大于RT那么继续熔断,否则放行通过

image.png

5.2.2 具体案例

@GetMapping("/testC")  
public String testC(){  
    try {  
        TimeUnit.SECONDS.sleep(5);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
    return "--testC";  
}

设置熔断策略,1QPS>5 并且这些请求的RT>300 并且大于比例阈值触发熔断

image.png
通过JMeter测试,1秒钟发起10个线程请求/testC,此时就会触发熔断效果,停止测试以后,10秒钟以后恢复正常

image.png

5.3 熔断策略-异常比例

5.3.1 介绍

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

注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。

image.png

简单理解就是:

image.png

5.3.2 具体案例

设置熔断策略异常比例
image.png


@GetMapping("/testC")  
public String testC(){  
    try {  
        TimeUnit.SECONDS.sleep(5);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
    return "--testC";  
}

灵JMeter压测工具,一秒钟发送10个请求,启动后就会触发熔断

image.png

5.4 熔断策略-异常数

5.4.1 概述

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

注意:异常降级仅针对业务异常,对Sentinel限流降级本身的异常(BlockException)不生效。

image.png

简单理解就是:
image.png

5.4.2 具体案例

@GetMapping("/testD")  
public String testD(Long id ){  
    if(id > 5){  
        throw new RuntimeException("运行时异常");  
    }  
    return testService.common();  
}

设置异常数策略,当1秒钟内请求超过5并且异常数大约5个的时候触发熔断

image.png

浏览器验证触发熔断异常

image.png

六、热点规则

6.1 概念

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制

  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效
官网:https://sentinelguard.io/zh-cn/docs/parameter-flow-control.html

image.png
image.png

6.2 使用@SentinelResource注解

其实这个热点限流其实就是更加细粒度的流控规则,那么如果想使用它就必须要配合对应SentinelResource注解。

Sentinel 提供了 @SentinelResource 注解用于定义资源,它有很多的参数,我们这里主要关注两个参数:

  1. value:代表资源名称,必需项,因为需要通过resource name找到对应的规则,这个是必须配置的

  2. blockHandler:blockHandler 对应处理 BlockException 的方法名称,可选项,访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。

6.3 热点规则(一)–具体案例

image.png

 @GetMapping("/testHotKey")  
@SentinelResource("testHotKey")  
public String testE(@RequestParam(value = "hot1",required = false) String hot1,  
                    @RequestParam(value = "hot2",required = false)String hot2,  
                    @RequestParam(value = "hot13",required = false) String hot3){  
    return "----testHotKey";  
}

配置热点规则

注意:这里是给资源配置热点规则,不是接口名称

这个参数索引,指的就是我们参数下标

image.png

浏览器快速访问一秒多个请求,就会出现限流

image.png
刚刚浏览器返回错误页面,对用户不友好。可以利用@SentinelResource注解提供的另外一个参数blockHandler,这个参数是可以指定当出现异常时的处理方法

@GetMapping("/testHotKey")  
@SentinelResource(value = "testHotKey", blockHandler = "handler_HotKey")  
public String testE(@RequestParam(value = "hot1",required = false) String hot1,  
                    @RequestParam(value = "hot2",required = false)String hot2,  
                    @RequestParam(value = "hot13",required = false) String hot3){  
    return "----testHotKey";  
}  
  
//处理异常方法,方法签名要和对应的接口方法保持一致  
public String handler_HotKey(String hot1, String hot2, String hot3, BlockException exception){  
    return "系统繁忙稍后重试。。";  
}

注意:blockHandler = “handler_HotKey” 要保证和接口名称的返回类型,方法签名保持一致,并且在后面多增加一个参数BlockException

配置规则不变,我们快速访问浏览器
image.png

6.4 热点规则(二)–具体案例

image.png

6.4.1 参数例外项

其实参数例外项就是可以达到更加细粒度的控制,比如我们当前的例子中,目前hot1参数在访问时超过阈值就会被限流,但是我们可以通过参数例外项设置hot1具体等于特殊的某个值的时候,触发不同的限流效果。假如hot1的值等于5时,它的阈值可以达到200。

**注意:参数例外项中的参数类型仅支持一下7种数据类型

image.png

6.4.2 具体案例

当前我们需要让hot1的值为5的时候阈值可以达到200,首先Sentinel页面中修改对应热点规则

image.png
此时的规则为:如果当前hot1值为除5以外的其他值,都会走普通的阈值规则,但是如果一旦hot1的值为5的时候,将会走参数例外项,此时的阈值为200,我们通过浏览器测试,当hot1的值等于5是只要阈值不超过200就不会出现限流。

image.png
注意:我们到现在代码中使用了@SentinelResource注解,此注解处理的是Sentinel控制台配置的异常,通过blockHandler属性设置对应方法来处理和程序本身异常无关。如果是程序异常还是会报程序异常

七、Sentinel系统规则

Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

7.1 系统规则

系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。

系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量,比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。

image.png

7.2 系统规则支持以下模式

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1(1分钟平均负载) 作为启发指标,进行自适应系统保护。当系统 load1(1分钟平均负载) 超过设定的启发值(阈值),且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps(秒级统计的最大QPS) * minRt(秒级统计的最小响应时间) 估算得出。设定参考值一般是 CPU cores * 2.5
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护

image.png

7.3 具体案例

入口QPS来进行测试,直接设置规则

image.png

最后我们不管访问那个接口都会出现限流

八、@SentinelResource自定义限流逻辑处理

Sentinel 提供了@SentinelResource注解用于定义资源,并提供了AspectJ的扩展用于自定义资源,处理BlockException等。

8.1 @SentinelResource 资源限流

编写一个新的控制器类型SentinelResourceTestController,使用@SentinelResource注解同时使用blockHandler属性

@GetMapping("/byResource")  
@SentinelResource(value = "byResource",blockHandler = "handler_resource")  
public String byResource(){  
    return "-----byResource";  
}  
  
public String handler_resource(BlockException exception){  
    return "系统繁忙";  
}

配置流控规则

image.png

快速访问浏览器,触发限流规则

image.png

8.2 @SentinelResource URL限流

核心点:使用@SentinelResource注解,但是不使用blockHandler属性,系统会调用默认限流异常处理方法。

其实这个注解,我们还可以更换请求地址为资源,比如我们在新建一个测试接口方法

@GetMapping("/byRest")
@SentinelResource(value = "/byRest")
public String byRest(){
    return "-----byRest";
}

给这个接口地址添加流控

image.png

如果没有这个接口增加自定义限流处理方法,则还是会走默认的

image.png

由此我们得出:

  1. @SentinelResource 既可以配置资源名称也可以配置URL

  2. 如果配置了@SentinelResource的blockHandler属性对应方法,出现限流会调用对应方法

  3. 如果没有配置@SentinelResource的blockHandler属性,系统会走默认的限流处理。

8.3 自定义限流逻辑处理

@SentinelResource除了blockHandler可以设置自定义限流处理逻辑方法以外,还提供另外一个属性来设置限流处理逻辑类型blockHandlerClass属性,此属性中设置的方法必需为 static 函数,否则无法解析。

这样就不用把一个自定义处理限流的方法写在一个类里面,解耦出来


/**
 * 此类型用来处理限流自定义逻辑
 */
public class CustomerBlockHandler {
    public static String handlerException1(BlockException exception){
        return "handlerException1:系统异常,请稍后重试!";
    }
    public static String handlerException2(BlockException exception){
        return "handlerException2:网络崩溃了,请稍后重试!";
    }
}

/**
* 此方法用到了自定义限流处理类型CustomerBlockHandler
* 中的handlerException1方法来处理限流逻辑。
*/
@GetMapping("/bycustomer")
@SentinelResource(value = "bycustomer",
                  blockHandlerClass = CustomerBlockHandler.class,
                  blockHandler = "handlerException1")
public String bycustomer(){
    return "-----bycustomer";
}

给bycustomer资源添加限流规则,然后来测试在超过限流阈值时处理方法是否为CustomerBlockHandler中handlerException1来进行处理。

8.4 @SentinelResource中的fallback属性

8.4.1 概念

fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:

  • 返回值类型必须与原函数返回值类型一致;
  • 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
  • fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
    其实通过官网上提供的概念,我们不难看出这个属性类似于blockHandler,但是各位一定要注意他们有本质的不同。

**注意:fallback属性和blockHandler属性的本质不同在于他们作用的异常不同:

  • blockHandler:针对违反Sentinel控制台配置规则时触发BlockException异常时对应处理的属性
  • fallback:针对Java本身出现的异常进行处理的对应属性。

8.4.2 具体案例

其实fallback和blockHandler的用法基本一样。可以在当前方法的类中,也可以通过fallbackClass指定某一个类中去写异常的处理

8.5 exceptionsToIgnore属性

  • exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

基本用法如下所示:


@SentinelResource(value = "falllback",fallback = "fallbackHandler",blockHandler = "blockHandler", exceptionsToIgnore = {NullPointerException.class})//被标注的异常将会被 原样抛出

如果对你有帮助,可以关注博主(不定期更新各种技术文档)

给博主一个免费的点赞以示鼓励,谢谢 ! 欢迎各位🔎点赞👍评论收藏⭐️

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

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

相关文章

vue的element ui使用el-table组件实现懒加载树、默认自动展开层级(一层,二层)、并且解决新增、删除、修改之后树节点不刷新问题

1.整体思路 问题&#xff1a;数据量太大了&#xff0c;导致接口返回数据时间较长。解决: 将ElementUi中Table组件加载改为懒加载&#xff08;查看文档&#xff09;。思路&#xff1a;初始化打开页面时只显示第一级菜单,用户点击展开菜单之后往后端发送请求,然后加载出一级子菜…

python接口自动化(十)--post请求四种传送正文方式(详解)

1.简介 post请求我在python接口自动化&#xff08;八&#xff09;--发送post请求的接口&#xff08;详解&#xff09;已经讲过一部分了&#xff0c;主要是发送一些较长的数据&#xff0c;还有就是数据比较安全等。我们要知道post请求四种传送正文方式首先需要先了解一下常见的四…

快速入门java网络编程基础------Nio

一. NIO 基础 哔哩哔哩黑马程序员 netty实战视频 0.什么是nio&#xff1f; NIO&#xff08;New I/O&#xff09;是Java中提供的一种基于通道和缓冲区的I/O&#xff08;Input/Output&#xff09;模型。它是相对于传统的IO&#xff08;InputStream和OutputStream&#xff09;模型…

Java SPI机制总结系列之开发入门实例

原创/朱季谦 在该文章正式开始前&#xff0c;先对 Java SPI是什么做一个简单的介绍。 SPI&#xff0c;是Service Provider Interface的缩写&#xff0c;即服务提供者接口&#xff0c;单从字面上看比较抽象&#xff0c;你可以理解成&#xff0c;该机制就像Spring容器一样&…

机器学习---lightGBM

1. lightGBM演进过程 AdaBoost是⼀种提升树的方法&#xff0c;和三个臭皮匠&#xff0c;赛过诸葛亮的道理⼀样。 AdaBoost两个问题&#xff1a; (1) 如何改变训练数据的权重或概率分布提高前⼀轮被弱分类器错误分类的样本的权重&#xff0c;降低前⼀ 轮被分对的权重 (2) 如何…

远程登陆利器 ssh

文章目录 远程登陆利器 ssh登陆远程服务器指定用户名多数情况的登陆方式查看服务器的时间指定端口更多信息 远程登陆利器 ssh ssh命令是openssh套件中的客户端连接工具&#xff0c;使用加密协议实现安全的远程登录服务器&#xff0c;实现对服务器的远程管理。 官方定义为&…

[学习笔记]刘知远团队大模型技术与交叉应用L1-NLPBig Model Basics

本节主要介绍NLP和大模型的基础知识。提及了词表示如何从one-hot发展到Word Embedding。语言模型如何从N-gram发展成预训练语言模型PLMs。然后介绍了大模型在NLP任务上的表现&#xff0c;以及它遵循的基本范式。最后介绍了本课程需要用到的编程环境和GPU服务器。 一篇NLP方向的…

还在因为版本不一致重装node吗,用它试试

一、卸载nodejs 首先卸载已安装的nodejs&#xff0c;总体分三步 1)打开控制面板&#xff0c;卸载nodejs 2)打开计算机->高级->环境变量&#xff0c;删除path中nodejs相关的配置 3)打开nodejs安装目录&#xff0c;整体删除 打开cmd&#xff0c;输入以下命令&#xff…

Android Studio下载gradle反复失败

我的版本&#xff1a;gradle-5.1.1 首先检查设置路径是否正确&#xff0c;参考我的修改&#xff01; 解决方案 1.手动下载Gradle.bin Gradle Distributions 下载地址 注意根据编译器提示下载&#xff0c;我这要求下载的是bin 而不是all 2.把下载好的整个压缩包放在C:\Users\…

Uniapp软件库源码-全新带勋章等

测试环境&#xff1a;php7.1。ng1.2&#xff0c;MySQL 5.6 常见问题&#xff1a; 配置好登录后转圈圈&#xff0c;检查环境及伪静态以及后台创建好应用 上传图片不了&#xff0c;检查php拓展fileinfo 以及public文件权限 App个人主页随机背景图&#xff0c;在前端uitl文件夹里面…

数组深入详解

1、什么是数组&#xff1f; Java 语言中提供的数组是用来存储固定大小的同类型元素。 如&#xff1a;可以声明一个数组变量&#xff0c;如 numbers[100] 来代替直接声明 100 个独立变量 number0&#xff0c;number1&#xff0c;…&#xff0c;number99。 注意事项&#xff1a;…

第二百六十六回

文章目录 1. 概念介绍2. 分析与解决2.1 分析问题2.2 解决方案 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何修改CircleAvatar的大小"相关的内容&#xff0c;本章回中将介绍如何修改StatusBar中文字的颜色.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1.…

鸿蒙Harmony-层叠布局(Stack)详解

我们总是为了太多遥不可及的东西去拼命&#xff0c;却忘了人生真正的幸福不过是灯火阑珊处的温暖&#xff0c;柴米油盐的充实&#xff0c;人生无论你赚的钱&#xff0c;是多还是少&#xff0c;经历的事情是好还是坏&#xff0c;都不如过好当下的每一天&#xff01; 目录 一&am…

CF1178F1 Short Colorful Strip 题解

Short Colorful Strip 传送门 题面翻译 题目描述 这是F题的第一个子任务。F1和F2的区别仅在对于m和时间的限制上 有n1种颜色标号从0到n&#xff0c;我们有一条全部染成颜色0的长为m的纸带。 Alice拿着刷子通过以下的过程来给纸带染色&#xff1a; 我们按照从1到n的顺序进…

美国初创公司Rabbit推出口袋AI设备R1;吴恩达课程:使用LangChain.js构建强大的JavaScript应用

&#x1f989; AI新闻 &#x1f680; 美国初创公司Rabbit推出口袋AI设备R1&#xff0c;短时间内被抢购一空 摘要&#xff1a;美国初创公司Rabbit在CES 2024上发布了口袋AI设备R1&#xff0c;这款设备在一天内被抢购一空&#xff0c;售价为199美元。R1具有小巧玲珑的触屏、摄像…

【线性表的基本操作实现及其应用 】

线性表的基本操作实现及其应用 1.实验目的 ⑴ 熟练掌握线性表的基本操作在两种存储结构上的实现&#xff0c;其中以熟悉各种链表的操作为重点。 ⑵ 巩固高级语言程序设计方法与技术&#xff0c;会用线性链表解决简单的实际问题。 2.实验原理与要求 ⑴ 按照数据结构实验任务书&…

【笔记】书生·浦语大模型实战营——第四课(XTuner 大模型单卡低成本微调实战)

【参考&#xff1a;tutorial/xtuner/README.md at main InternLM/tutorial】 【参考&#xff1a;(4)XTuner 大模型单卡低成本微调实战_哔哩哔哩_bilibili-【OpenMMLab】】 总结 学到了 linux系统中 tmux 的使用 了解了 XTuner 大模型微调框架的使用 pth格式参数转Hugging …

【量化交易故事】小明开启了量化创业之旅-01

故事开始于2023年的春天&#xff0c;小明是一位对金融市场充满热情的IT工程师。在经历了数次基于主观判断和个人情绪进行投资却收获平平后&#xff0c;他意识到传统交易方式中的人为因素难以避免&#xff0c;而这往往成为影响投资决策稳定性和准确性的关键障碍。在一次偶然的机…

工作压力测试

每个职场人都会遇到工作压力&#xff0c;在企业人力资源管理的角度来看&#xff0c;没有工作压力是人力资源的低效&#xff0c;适当的工作压力可以促使员工不断进取&#xff0c;然而每个人的抗压能力是不同的&#xff0c;同样的工作量和工作难度&#xff0c;不同的人在面对相同…

【Java语言基础②】Java基本语法——Java程序基本格式,注释,标识符,常量

通过前面的学习&#xff0c;大家对Java语言有了一个基础认识&#xff0c;但现在还无法使用Java语言编写程序&#xff0c;要熟练使用Java语言编写程序&#xff0c;必须充分掌握Java语言的基础知识。今天咱们就来聊一聊Java的基本语法。 1.java程序的基本格式 Java程序代码必须…