1.开篇
继前几篇文章中的内容,学完了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能够干嘛?
整个Sentinel组件由两部分构成:
· 核心库(Java客户端)不依赖任何框架/库,能够运行于所有Java运行时环境,同时对 Dubbo /Spring Cloud等框架也有较好的支持。
· 控制台(Dashboard)基于Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat等应用容器。
下载完Sentinel的jar包之后,直接java -jar运行即可。之后在浏览器中输入localhost:8080即可访问,账号密码都是 sentinel。在访问之前一定确保8080端口没有被占用(tomcat)。
2.项目源码
github源码地址:https://github.com/2656307671/SpringCloud-Alibaba-Sentinel
gitee源码地址:https://gitee.com/szh-forever-young/SpringCloud-Alibaba-Sentinel
本次做Sentinel测试的代码请参考上面的仓库。
下面,我们启动测试,这里我考虑到电脑的性能、内存占用等问题,所以nacos直接在windows端启动了,然后启动sentinel,同时启动8401微服务模块。
此时,nacos和sentinel都启动成功,但是我们刷新sentinel的页面,发现并没有微服务出现。这是因为sentinel默认采用了懒加载机制。
这里需要我们访问一次controller才OK。
此时就可以在热点链路中看到我们上面访问的testA、testB。
当在浏览器中多次访问testA或者testB的时候,可以在sentinel的实时监控中看到请求的曲线图变化情况。
3.流控规则
上面简单说了一下sentinel是什么?下载安装、简单测试。
下面来说说sentinel的核心重要操作了,先说这个流控规则,对应于sentinel界面中的这个位置:👇👇👇
· 资源名: 唯一名称,默认请求路径。
· 针对来源: 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的默认错误页面的提示信息。
3.2 流控模式:关联
· 当关联的资源达到阈值时,就限流自己。
· 当与A关联的资源B达到阀值后,就限流A自己。B惹事,但是A却挂了。。。
当关联资源/testB的QPS阀值超过1时,就限流/testA的Rest访问地址,当关联资源到阈值后限制配置好的资源名。
这里使用Postman来模拟并发密集访问 testB,添加一个集合,在其中设置关于 testB 请求的并发访问信息:20个线程每间隔0.3秒访问一次。
Run之后,testB就面临着高并发的访问压力,也就是说B惹事了;到浏览器中访问testA,可以看到 testA 得到的是sentinel系统默认的出错提示页面。
我们要求的是每秒钟访问一次testB,而Postman中设置了每隔0.3秒访问20次testB,肯定已经超越了B的阈值。
也即:当与A关联的资源B达到阀值后,就限流A自己。
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
测试结果这里截图不便,情况就是:刚开始我们快速多次的访问localhost:8041/testB,一秒钟之内超过10/3=3次,那么此时直接出现sentinel的默认出错页面信息。当慢慢的预热了4秒之后,此时阈值达到了10,我们再像之前那样快速多次的访问testB,页面就恢复正常了。
这种预热的流控效果多应用于:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。
3.5 流控效果:排队等待
匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。
排队等待设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
Postman设置含义:每隔1秒,就有10个线程过来访问B。
在IDEA的控制台中,可以看到详细的日志信息,每隔1秒出现一条日志