1.开篇

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba

继前几篇文章中的内容,学完了SpringCloud Alibaba的Nacos服务注册与配置中心、集群搭建、持久化配置。那么接下来肯定要看看最新的关于服务熔断与限流的技术了,也就是SpringCloud Alibaba的Sentinel。

官网:https://github.com/alibaba/Sentinel,Sentinel在官网给出的解释是:轻量级的流量控制、熔断降级Java库。

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。

既然要使用Sentinel来做服务熔断与降级,那就需要和之前的Nacos一样,下载安装运行。链接:https://github.com/alibaba/Sentinel/releases/tag/1.7.0

下面先来看看Sentinel能够干嘛?

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_java_02

整个Sentinel组件由两部分构成:

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

下载完Sentinel的jar包之后,直接java -jar运行即可。之后在浏览器中输入localhost:8080即可访问,账号密码都是 sentinel。在访问之前一定确保8080端口没有被占用(tomcat)。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_03

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_java_04

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_05


2.项目源码

github源码地址:https://github.com/2656307671/SpringCloud-Alibaba-Sentinel

gitee源码地址:https://gitee.com/szh-forever-young/SpringCloud-Alibaba-Sentinel

本次做Sentinel测试的代码请参考上面的仓库。

下面,我们启动测试,这里我考虑到电脑的性能、内存占用等问题,所以nacos直接在windows端启动了,然后启动sentinel,同时启动8401微服务模块。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_06

此时,nacos和sentinel都启动成功,但是我们刷新sentinel的页面,发现并没有微服务出现。这是因为sentinel默认采用了懒加载机制。

这里需要我们访问一次controller才OK。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_07

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_08

此时就可以在热点链路中看到我们上面访问的testA、testB。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_09

当在浏览器中多次访问testA或者testB的时候,可以在sentinel的实时监控中看到请求的曲线图变化情况。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_10


3.流控规则

上面简单说了一下sentinel是什么?下载安装、简单测试。

下面来说说sentinel的核心重要操作了,先说这个流控规则,对应于sentinel界面中的这个位置:👇👇👇

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_微服务_11

  • 资源名:  唯一名称,默认请求路径。
  • 针对来源:  Sentinel可以针对调用者进行限流,填写微服务名,默认default (不区分来源)·阈值类型/单机阈值:

              QPS(每秒钟的请求数量):  当调用该api的QPS达到阈值的时候,进行限流。

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

  • 是否集群:  不需要集群。
  • 流控模式:

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

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

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

  • 流控效果:

               快速失败:   直接失败,抛异常。

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

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

3.1 流控模式:直接

这是sentinel系统默认的流控模式。

见如下配置,表示1秒钟内查询1次就是OK,若超过次数1,就直接-快速失败,报默认错误。

在浏览器中快速多次的访问 localhost:8401/testA,即可看到sentinel的默认错误页面的提示信息。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_12

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_13

3.2 流控模式:关联

  • 当关联的资源达到阈值时,就限流自己。
  • 当与A关联的资源B达到阀值后,就限流A自己。B惹事,但是A却挂了。。。

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

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_14

这里使用Postman来模拟并发密集访问 testB,添加一个集合,在其中设置关于 testB 请求的并发访问信息:20个线程每间隔0.3秒访问一次。

Run之后,testB就面临着高并发的访问压力,也就是说B惹事了;到浏览器中访问testA,可以看到 testA 得到的是sentinel系统默认的出错提示页面。

我们要求的是每秒钟访问一次testB,而Postman中设置了每隔0.3秒访问20次testB,肯定已经超越了B的阈值。

也即:当与A关联的资源B达到阀值后,就限流A自己。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_java_15

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_16

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_java_17

3.3 流控效果:快速失败

快速失败其实就是和流控模式中的直接相匹配的,直接 ---> 快速失败。失败,直接反馈sentinel系统的默认出错页面信息。

参考上面的3.1。

3.4 流控效果:预热

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

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

关于预热的配置如下:👇👇👇

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

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

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_spring cloud alibaba_18

测试结果这里截图不便,情况就是:刚开始我们快速多次的访问 localhost:8041/testB,一秒钟之内超过10/3=3次,那么此时直接出现sentinel的默认出错页面信息。当慢慢的预热了4秒之后,此时阈值达到了10,我们再像之前那样快速多次的访问testB,页面就恢复正常了。

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

3.5 流控效果:排队等待

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

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

Postman设置含义:每隔1秒,就有10个线程过来访问B。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_限流_19

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_微服务_20

在IDEA的控制台中,可以看到详细的日志信息,每隔1秒出现一条日志。

SpringCloud Alibaba——Sentinel服务熔断与限流(一、流控规则)_微服务_21