「SpringCloud Alibaba」Sentinel实现熔断与限流

SpringCloud Alibaba—Sentinel实现熔断与限流

笔记整理自【尚硅谷】周阳SpringCloud框架开发教程

「SpringCloud Alibaba」Sentinel实现熔断与限流_第1张图片

「SpringCloud Alibaba」Sentinel实现熔断与限流_第2张图片

1. Sentinel简介

「SpringCloud Alibaba」Sentinel实现熔断与限流_第3张图片

「SpringCloud Alibaba」Sentinel实现熔断与限流_第4张图片

一句话,Sentinel就是升级的Hystrix。

Ⅰ. Sentinel是什么

官网

  • 英文
  • 中文

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

Sentinel 具有以下特征:

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

Ⅱ. Sentinel能做什么

Sentinel 的主要特性

「SpringCloud Alibaba」Sentinel实现熔断与限流_第5张图片

Sentinel 的开源生态

Ⅲ. Sentinel怎么使用

官网使用教程

服务使用中的各种问题

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

「SpringCloud Alibaba」Sentinel实现熔断与限流_第6张图片

2. 安装Sentinel控制台

Sentinel 分为两个部分:

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

安装步骤

  • 下载到本地:sentinel-dashboard-1.8.5.jar

  • 运行命令

    java -jar sentinel-dashboard-1.8.5.jar
    

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第7张图片

    前提需要java8环境,且8080端口不能被占用。

  • 访问 http://localhost:8080,账号密码均为sentinel

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第8张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第9张图片

3. 初始化演示工程

  • 启动Nacos8848成功

    http://localhost:8848/nacos/#/login

  • 建Module

    cloudalibaba-sentinel-service8401

  • 改POM

    下面这3个依赖就是Nacos + Sentinel的标配

    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
    dependency>
    

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第10张图片

    OpenFeign后面会用到。

  • 写YML

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第11张图片

  • 主启动

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第12张图片

  • 业务类

    FlowLimitController

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第13张图片

  • 测试

    ➢ 启动Sentinel8080

    ➢ 启动微服务8401

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第14张图片

    ➢ 查看sentienl控制台

    空空如也,啥都没有

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第15张图片

    ➢ Sentinel采用的懒加载说明

    执行一次访问即可

    http://localhost:8401/testA

    http://localhost:8401/testB

    ➢ 效果

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第16张图片

    Sentinel8080正在监控微服务8401。

4. 流控规则

Ⅰ. 基本介绍

流量限制控制规则,分为:流控模式流控效果

「SpringCloud Alibaba」Sentinel实现熔断与限流_第17张图片

解释说明

「SpringCloud Alibaba」Sentinel实现熔断与限流_第18张图片

Ⅱ. 流控模式

1️⃣ 直接(默认)

api达到限流条件时,直接限流

  • 直接 => 快速失败(系统默认)

  • 可以直接点击簇点链路添加流控

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第19张图片

  • 配置及说明

    阈值类型为QPS

    表示1秒钟内查询1次就是OK,若超过次数1,就直接 => 快速失败,报默认错误

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第20张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第21张图片

  • 测试

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

    ➢ 结果

    Blocked by Sentinel (flow limiting)

    image-20220911202238429

    ➢ 思考

    直接调用默认报错信息,技术方面OK,但,是否应该有我们自己的后续处理?

    比如:类似有个fallback的兜底方法?

扩展:阈值类型为线程数

「SpringCloud Alibaba」Sentinel实现熔断与限流_第22张图片

当调用该api的线程数达到阈值的时候,进行限流。

与QPS直接快速失败不同的是,QPS情况下限制的是流量,比如银行的人流量只能是1人/s,也就是说每秒只能一个人进入银行办理业务;

而线程数就好比银行只有一个窗口开放,一群人都可以进入银行,但是每次只能处理一个人的业务

  • 演示效果

    修改一下8401的业务类:

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第23张图片

  • 测试

    开两个页面访问:http://localhost:8401/testA

    同时抢占,一个直接快速失败,另一个在处理请求

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第24张图片

2️⃣ 关联

当关联的资源达到阈值时,就限流自己

  • 当与A关联的资源B达到阀值后,就限流A自己
  • B惹事,A挂了
  • 配置A

    设置效果

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

    Ex:假如支付接口/testB即将瘫痪,那么限制下单接口/testA。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第25张图片

  • postman模拟并发密集访问testB

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第26张图片

    ➢ 访问testB成功

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第27张图片

    ➢ postman里新建多线程集合组

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第28张图片

    ➢ 将访问地址添加进新新线程组

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第29张图片

    ➢ Run

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第30张图片

    大批量线程高并发访问B,导致A失效了。

    image-20220911220807109

3️⃣ 链路

多个请求调用了同一个微服务。

只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。

需要测试链路的话,Spring Cloud Alibaba 版本需要2.1.1.RELEASE以上,在父工程的pom中修改,不要直接在子odule的pom中修改,版本有对应关系,不然报错。

<dependency>
    <groupId>com.alibaba.cloudgroupId>
    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    <version>2.1.1.RELEASEversion>
    <type>pomtype>
    <scope>importscope>
dependency>
  • Sentinel从1.6.3版本开始,Sentinel Web Filter 默认收敛所有的URL入口的Context,因此链路限流不生效

  • 1.7.0版本开始,官方在CommomFilter中引入了WEB_CONTEXT_UNIFY这个init parameter,用于控制是否收敛context,将其配置为false即可根据不同的URL进行链路限流

  • Spring Cloud Alibaba 在2.1.1.RELEASE版本后,可以通过配置spring.cloud.sentinel.web-context-unify=false关闭

  • 参考

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第31张图片

  • 测试

    启动8401,给/testA设置链路 + 快速失败流控规则,入口资源填写/testA的入口资源地址sentinel_web_servlet_context

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第32张图片

    然后再发送请求至 http://localhost:8401/testA 时,如果1秒内请求次数超过1次,就会自动触发限流。
    此外,通过其他微服务模块请求/testA时,如果1秒内请求次数超过1次,同样会触发限流。

    image-20220912112808877

    但是不会对/testB限制。

  • 解释

    实际上,链路的控制指的就是对一条链路的访问进行控制。

    比方说,我有一个二叉树:

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第33张图片

    a => b => d,a => b => e,a => c => f,a => c => g 均可视作链路。

    假设我以a为入口资源,d为终点资源,对这条链路进行限制的话,则资源a,b,d均会被限制访问。

Ⅲ. 流控效果

1️⃣ 直接 => 快速失败(默认的流控处理)

直接失败,抛出异常

Blocked by Sentinel (flow limiting)

  • 源码

    com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

2️⃣ Warm Up 预热

根据codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。

  • 公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值。

  • 官网

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第34张图片

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

    限流 冷启动

  • 源码

    image-20220912105125511

  • Warm Up配置

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

    案例,阀值为10,预热时长设置5秒。
    系统初始化的阀值为10 / 3 约等于3,即阀值刚开始为3;然后过了5秒后阀值才慢慢升高恢复到10。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第35张图片

  • 测试

    多次点击:http://localhost:8401/testB

    刚开始扛不住,后续慢慢的能抗住了:

    B

  • 应用场景

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

3️⃣ 排队等待

匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。

  • 官网

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第36张图片

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

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第37张图片

    匀速排队,阈值必须设置为QPS。

  • 源码

    com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

  • 测试

    @GetMapping("/testB")
    public String testB() {
        log.info(Thread.currentThread().getName() + "\t" + "...testB");
        return "-----testB";
    }
    

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第38张图片

    可以看到刚好满足1s一个请求,说明请求的执行进行了排队。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第39张图片

5. 降级规则

Ⅰ. 基本介绍

官网

Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。

当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

老版本的Sentinel的断路器是没有半开状态的,半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考Hystrix(在Hystrix中 快照时间窗口是值 阈值检测时间 ,而休眠时间窗口是指 断路器从开启到半开状态间隔的时间)。

新版本的Sentinel加入了半开状态!

Sentinel在1.8.0版本对熔断降级做了大的调整,可以定义任意时长的熔断时间,引入了半开启恢复支持。下面梳理下相关特性。

熔断状态

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

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

熔断降级规则说明

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

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

Ⅱ. 降级策略实战

1️⃣ 慢调用比例,RT(平均响应时间,秒级)

老版本:

「SpringCloud Alibaba」Sentinel实现熔断与限流_第40张图片

「SpringCloud Alibaba」Sentinel实现熔断与限流_第41张图片

新版本:

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

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第42张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第43张图片

测试

  • 代码

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第44张图片

  • 配置

    熔断规则

    在1000ms的统计时间内,总请求数(超过5次)中有80%的请求最大RT超过了200ms,那么触发熔断机制,熔断2s。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第45张图片

  • jmeter压测

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第46张图片

  • 结论

    永远一秒钟打进来10个线程(大于5个了)调用testD,我们希望200毫秒处理完本次任务,如果超过200毫秒还没处理完,在未来s秒钟的时间内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电了。

    testD被熔断了:

    image-20220912141953180

    从实时监控也可以看到,在09的时候开始熔断:

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第47张图片

    后续停止jmeter,没有这么大的访问量了,断路器半开到关闭(保险丝恢复),微服务恢复OK。

2️⃣ 异常比例(秒级)

老版本:

image-20220912131709616

「SpringCloud Alibaba」Sentinel实现熔断与限流_第48张图片

新版本:

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

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第49张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第50张图片

测试

  • 代码

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第51张图片

  • 配置

    熔断规则

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第52张图片

  • jmeter压测

  • 结论

    单独访问一次,必然来一次报错一次 (int age = 10/0) ,调一次错一次;

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第53张图片

    开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了,断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了。

    image-20220912151236430

    停掉jemeter后过2s,报/zero错误。

3️⃣ 异常数(分钟级)

老版本:

image-20220912131944957

「SpringCloud Alibaba」Sentinel实现熔断与限流_第54张图片

新版本:

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

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第55张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第56张图片

测试

  • 代码

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第57张图片

  • 配置

    熔断规则

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第58张图片

  • 手动测试

  • 结论

    image-20220912154512510

    这里测试出现了Bug,虽然熔断了 但熔断时长不是我配置的5s,熔断了很久大概1分钟,统计时长也不是1s,因为我手动很慢的测试,同时没达到最小请求数,只达到3次异常就直接熔断了。但老师演示的老版本就可以依据配置进行熔断,可能是不会使用新版本。

    我发现我根本改不了配置的统计时长,如果按照老版本的是按照分钟统计异常数,设置时间窗口 >= 60s,那新版本理应设置统计时长 >= 60000ms,但我修改统计时长后再编辑 还是默认的1000,虽然新版本没说异常数是分钟级的,但是修改不了统计时长就很迷惑。上面修改慢调用比例的比例阈值也没效果,但异常比例的比例阈值可以修改。

    搞不懂。

6. 热点key限流

Ⅰ. 基本介绍

官网

何为热点

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

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

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

「SpringCloud Alibaba」Sentinel实现熔断与限流_第59张图片

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。

「SpringCloud Alibaba」Sentinel实现熔断与限流_第60张图片

承上启下复习

兜底方法

  • 分为 系统默认 和 客户自定义,两种
  • 之前的case,限流出问题后,都是用Sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
  • 我们能不能自定义 类似Hystrix,某个方法出问题了,就找对应的兜底降级方法?

结论

  • @HystrixCommand@SentinelResource

Ⅱ. 代码演示

  • 新增

    @SentinelResource

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第61张图片

    如果你违背了@SentinelResource对控制台配置的规则,就会执行兜底的方法。

  • 配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第62张图片

    这里资源名是根据 @SentinelResource 注解的 value 属性值配置的。

    限流模式只支持QPS模式,固定写死了。(这才叫热点)

    @SentinelResource注解的方法参数索引,0代表第一个参数,1代表第二个参数,以此类推。

    单机阀值以及统计窗口时长表示在此窗口时间超过阀值就限流。

    上面的抓图就是第一个参数有值的话,1秒的QPS为1,超过就限流,限流后调用dealHandler_testHotKey支持方法。

    image-20220912181135419

  • 测试

    ➢ 使用兜底方法

    http://localhost:8401/testHotKey?p1=a

    image-20220912181810675

    image-20220912182314903

    ➢ 不使用兜底方法

    http://localhost:8401/testHotKey?p1=a

    @SentinelResource注解中的blockHandler属性去掉:

    image-20220912182029354

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第63张图片

  • 小总结

    ➢ ❌ error http://localhost:8401/testHotKey?p1=abc

    ➢ ❌ error http://localhost:8401/testHotKey?p1=abc&p2=33

    ➢ ✔️ right http://localhost:8401/testHotKey?p2=abc

    只要带上p1参数且违背了规则 就会降级限流。

Ⅲ. 参数例外项

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

  • 特例情况

    ➢ 普通:超过1秒钟一个后,达到阈值1后马上被限流

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

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

  • 配置

    参数类型只支持8种基本类型和String类型。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第64张图片

    添加成功

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第65张图片

  • 测试

    ➢ ✔️ http://localhost:8401/testHotKey?p1=5

    image-20220912204531126

    ➢ ❌ http://localhost:8401/testHotKey?p1=3

    image-20220912204541459

    当p1等于5的时候,阈值变为200,当p1不等于5的时候,阈值就是平常的1。

7. 系统规则

官网

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

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

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

系统规则支持以下的模式:

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

「SpringCloud Alibaba」Sentinel实现熔断与限流_第66张图片

配置全局QPS

「SpringCloud Alibaba」Sentinel实现熔断与限流_第67张图片

  • 不管是/testA还是/testB,只要QPS > 1 整个系统就不能用。
  • 这个粒度太粗,就相当于一个窗口人很多,整个银行就不接待人了,不太建议使用。

8. @SentinelResource

Ⅰ. 按资源名称限流 + 后续处理

  • 启动Nacos成功

  • 启动Sentinel成功

  • 改Module

    修改cloudalibaba-sentinel-service8401

  • 改POM

    
    
    	com.atguigu.springcloud
    	cloud-api-commons
    	${project.version}
    
    

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第68张图片

  • 业务类

    RateLimitController

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第69张图片

  • 主启动

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第70张图片

  • 配置流控规则

    ➢ 配置步骤

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第71张图片

    ➢ 图形配置和代码关系

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第72张图片

    表示1秒钟内查询次数大于1,就跑到我们自定义的处理,限流。

  • 测试

    ➢ 1秒钟点击1下,OK

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第73张图片

    ➢ 超过上述,疯狂点击,返回了自己定义的限流处理信息,限流发生

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第74张图片

  • 额外问题

    此时关闭问服务8401看看

    Sentinel控制台,流控规则消失了??

    临时/持久?

Ⅱ. 按照Url地址限流 + 后续处理

通过访问的URL来限流,会返回Sentinel自带默认的限流处理信息。

  • 业务类

    RateLimitController

    不配置blockHandler属性,没有兜底方法。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第75张图片

  • Sentinel控制台配置

    这里是根据URL进行限流。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第76张图片

  • 测试

    ➢ 正常点击:http://localhost:8401/rateLimit/byUrl

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第77张图片

    ➢ 疯狂点击:http://localhost:8401/rateLimit/byUrl

    结果

    image-20220912214706293

    会返回Sentinel自带的限流处理结果。

Ⅲ. 上面兜底方案面临的问题

  • 系统默认的,没有体现我们自己的业务要求。
  • 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
  • 每个业务方法都添加一个兜底的,那代码膨胀加剧。
  • 全局统一的处理方法没有体现。

又回到了当时Hystrix的问题。

Ⅳ. 客户自定义限流处理逻辑

解决上述问题,创建CustomerBlockHandler类用于自定义限流处理逻辑。

  • 自定义限流处理类

    CustomerBlockHandler

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第78张图片

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第79张图片

  • 业务类

    RateLimitController

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第80张图片

  • Sentinel控制台配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第81张图片

  • 测试

    正常访问:http://localhost:8401/rateLimit/customerBlockHandler

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第82张图片

    狂点:http://localhost:8401/rateLimit/customerBlockHandler

    兜底的方法是全局的2号方法。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第83张图片

    完成了业务与代码的解耦,代码膨胀。

  • 进一步说明

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第84张图片

Ⅴ. 更多注解属性说明

注解支持文档

「SpringCloud Alibaba」Sentinel实现熔断与限流_第85张图片

「SpringCloud Alibaba」Sentinel实现熔断与限流_第86张图片

多说一嘴

「SpringCloud Alibaba」Sentinel实现熔断与限流_第87张图片

所有的代码都要用try-catch-finally方式进行处理。

Sentinel主要有三个核心Api

  • SphU定义资源
  • Tracer定义统计
  • ContextUtil定义了上下文

9. 服务熔断功能

Sentinel 整合 Ribbon + OpenFeign + fallback

Ⅰ. Ribbon系列

「SpringCloud Alibaba」Sentinel实现熔断与限流_第88张图片

1️⃣ 提供者9003/9004
  • 建Module

    新建cloudalibaba-provider-payment9003/9004两个一样的做法

  • 改POM

    <dependencies>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
        <dependency>
            <groupId>com.atguigu.springcloudgroupId>
            <artifactId>cloud-api-commonsartifactId>
            <version>${project.version}version>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
    dependencies>
    
  • 写YML

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第89张图片

  • 主启动

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第90张图片

  • 业务类

    模拟数据库的DAO层。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第91张图片

  • 测试

    ➢ http://localhost:9003/paymentSQL/1

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第92张图片

    ➢ http://localhost:9004/paymentSQL/1

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第93张图片

2️⃣ 消费者84
  • 建Module

    cloudalibaba-consumer-nacos-order84

  • 改POM

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第94张图片

  • 写YML

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第95张图片

  • 主启动

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第96张图片

  • 业务类

    config.ApplicationContextConfig

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第97张图片

    controller.CircleBreakerController

    目的:fallback管运行异常,blockHandler管配置违规。

    测试:http://localhost:84/consumer/fallback/1

    1️⃣ 没有任何配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第98张图片

    结果

    给客户error页面,不友好

    ➢ http://localhost:84/consumer/fallback/4

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第99张图片

    ➢ http://localhost:84/consumer/fallback/5

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第100张图片

    2️⃣ 只配置fallback

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第101张图片

    说明

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第102张图片

    本例Sentinel无配置。

    结果

    执行了兜底的handlerFallback方法。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第103张图片

    3️⃣ 只配置blockHandler

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第104张图片

    说明

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第105张图片

    本例sentinel需配置:

    异常超过2次后,断路器打开,断电跳闸,系统被保护。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第106张图片

    结果

    服务被降级。

    image-20220913145028460

    4️⃣ fallback和blockHandler都配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第107张图片

    说明

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第108张图片

    本例sentinel需配置:

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第109张图片

    结果

    没超过QPS,也就是没违反Sentinel中配置的规则,有运行异常则交给fallback处理:

    image-20220913145233226

    违反了Sentinel中配置的规则,即使有运行异常,降级也交给blockHandler处理:

    若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。

    5️⃣ 忽略属性…

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第110张图片

    说明

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第111张图片

    本例sentinel无配置。

    结果

    程序异常打到前台了,对用户不友好。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第112张图片

    其他页面没有影响:

    image-20220913150211778

    当然,触发流控之后,仍然通过blockHandler指定的方法进行熔断兜底。

  • 总结

    fallback + blockHandler两个一起配置,降级和限流的保护措施会更加完善。

Ⅱ. Feign系列

  • 改Module

    修改cloudalibaba-consumer-nacos-order84模块

    84消费者调用提供者9003

    Feign组件一般是消费侧

  • 改POM

    添加OpenFeign

    
    <dependency>
    	<groupId>org.springframework.cloudgroupId>
    	<artifactId>spring-cloud-starter-openfeignartifactId>
    dependency>
    
  • 写YML

    激活Sentinel对Feign的支持

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第113张图片

  • 主启动

    @EnableFeignClients

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第114张图片

  • 业务类

    ➢ 带@FeignClient注解的业务接口

    service.PaymentService

    image-20220913155225178

    ➢ 实现接口

    fallback = PaymentFallbackService.class => service.PaymentFallbackService

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第115张图片

    controller.CircleBreakerController

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第116张图片

  • 测试

    http://localhost:84/consumer/openfeign/1

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第117张图片

    测试84调用9003,此时故意关闭9003微服务提供者,看84消费侧自动降级,不会被耗死。

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第118张图片

Ⅲ. 熔断框架比较

「SpringCloud Alibaba」Sentinel实现熔断与限流_第119张图片

10. 规则持久化

一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化。

将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,Sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上Sentinel上的流控规则持续有效。

步骤

  • 改Module

    修改cloudalibaba-sentinel-service8401

  • 改POM

    之前已引入

    
    <dependency>
        <groupId>com.alibaba.cspgroupId>
        <artifactId>sentinel-datasource-nacosartifactId>
    dependency>
    
  • 写YML

    添加Nacos数据源配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第120张图片

  • 添加Nacos业务规则配置

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第121张图片

    [
        {
            "resource": "/rateLimit/byUrl",
            "limitApp": "default",
            "grade": 1,
            "count": 1,
            "strategy": 0,
            "controlBehavior": 0,
            "clusterMode": false
        }
    ]
    
    resource:资源名称;
    limitApp:来源应用;
    grade:阈值类型,0表示线程数,1表示QPS;
    count:单机阈值;
    strategy:流控模式,0表示直接,1表示关联,2表示链路;
    controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
    clusterMode:是否集群。
    
  • 启动8401后刷新sentinel发现业务规则有了

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第122张图片

  • 快速访问测试接口:http://localhost:8401/rateLimit/byUrl

    配置生效

    image-20220913170815600

  • 停止8401再看Sentinel

    停机后发现流控规则没有了

    「SpringCloud Alibaba」Sentinel实现熔断与限流_第123张图片

  • 重新启动8401再看Sentinel

    乍一看还是没有,稍等一会儿;

    多次调用:http://localhost:8401/rateLimit/byUrl

    配置重新出现了,持久化验证通过。

你可能感兴趣的:(#,SpringCloud,spring,cloud,cloud,alibaba,sentinel,微服务,java)