SpringCloud:Sentinel实现熔断与限流(1)

Sentinel  /  安装Sentinel控制台  /  初始化演示工程     /      流控规则

Sentinel

中文文档: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

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

Sentinel 是轻量级的流量控制、熔断降级Java库;功能类似于Hystrix

SpringCloud:Sentinel实现熔断与限流(1)

入门文档:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_sentinel

服务使用中的各种问题:服务雪崩、服务降级、服务熔断、服务限流

2.安装Sentinel控制台

Sentinel分为两个部分:

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

安装步骤

下载到本地sentinel-dashboard-1.8.2.jar
运行命令:
前提需要Java8,且8080端口不能被占用;java -jar sentinel-dashboard-1.8.2.jar

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

SpringCloud:Sentinel实现熔断与限流(1)

3.初始化演示工程

3.1 启动Nacos8848

3.2 新建工程

3.2.1 新建Module

cloudalibaba-sentinel-service8401

3.2.2 pom

以后基本上nacos 跟sentinel一起配置

pom.xml

3.2.3yaml

spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。
比如 Sentinel 控制台添加了1个限流规则,会把规则数据push给这个Http Server接收,Http Server再将规则注册到Sentinel中。
spring.cloud.sentinel.transport.port:指定与Sentinel控制台交互的端口,应用本地会启动一个占用该端口的Http Server

application.yaml

3.2.4主启动类

SentinelMainApp8401

3.2.5 业务类

FlowLimitController

3.3测试

启动Nacos8848,启动8401,启动Sentinel

查看Sentinel控制台,发现什么也没有

SpringCloud:Sentinel实现熔断与限流(1)

原因:Sentinel采用懒加载机制
执行一下:http://localhost:8401/testA

SpringCloud:Sentinel实现熔断与限流(1)

sentinel8080正在监控微服务8401

4.流控规则

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

SpringCloud:Sentinel实现熔断与限流(1)

SpringCloud:Sentinel实现熔断与限流(1)

4.1 流控模式

流控模式有三种:直接、关联、链路

SpringCloud:Sentinel实现熔断与限流(1)

4.1.1 直接(默认)+快速失败(默认)

(1) QPS直接快速失败

QPS:query per second,每秒钟的请求数量,当调用该api的QPS达到阈值时,进行限流。
下面设置表示1秒钟内查询一次就是OK,若QPS>1,就直接-快速失败,报默认错误

SpringCloud:Sentinel实现熔断与限流(1)

SpringCloud:Sentinel实现熔断与限流(1)

测试一下,当/testA的访问超过1次/s是,页面报错。被Sentinel限流,还能继续请求只要QPS<=1。

SpringCloud:Sentinel实现熔断与限流(1)

(2) 线程数直接快速失败

当调用该api的线程数达到阈值的时候,进行限流。
与QPS直接快速失败不同的是,QPS情况下限制的是流量,比如银行的人流量只能是1人/s,也就是说每次只能一个人进入银行办理业务;而线程数就好比银行只有一个窗口开放,一群人都可以进入银行,但是每次只能处理一个人的业务。

SpringCloud:Sentinel实现熔断与限流(1)

演示效果:
先修改一下8401的业务类

SpringCloud:Sentinel实现熔断与限流(1)

然后重启8401,测试/testA,最好用两个浏览器访问,效果更明显

SpringCloud:Sentinel实现熔断与限流(1)

4.1.2 关联

当关联的资源达到阈值时,就限流自己。比如当与A关联的资源B达到阈值后,就限流A自己。
例如:支付接口达到阈值,限流下订单的接口。

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

SpringCloud:Sentinel实现熔断与限流(1)

2. 测试
单独访问testB成功

SpringCloud:Sentinel实现熔断与限流(1)

postman模拟并发密集访问testB
先创建一个集合,名字自己随便取。

SpringCloud:Sentinel实现熔断与限流(1)

然后将创建的访问/testB的请求保存在创建的集合中

SpringCloud:Sentinel实现熔断与限流(1)

设定集合运行参数,20个线程,每次间隔0.3s访问一次(QPS>1),执行:

SpringCloud:Sentinel实现熔断与限流(1)

然后再访问/testA,发现被限流,等postman执行完毕,testA又可以访问了

SpringCloud:Sentinel实现熔断与限流(1)

4.1.3 链路

SpringCloud:Sentinel实现熔断与限流(1)

链路:只记录指定链路上的流量(指定资源人入口资源进来的流量,如果达到国值,就进行限流

4.2 流控效果

快速失败在上面的流控模式演示过了,他是默认的流控效果,直接失败,抛出异常。源码:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

4.2.1 warm up 预热

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

官网:https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81—%E5%86%B7%E5%90%AF%E5%8A%A8

源码:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值

SpringCloud:Sentinel实现熔断与限流(1)

SpringCloud:Sentinel实现熔断与限流(1)

测试

SpringCloud:Sentinel实现熔断与限流(1)

狂点请求,可以看通过的QPS逐渐增加,最开始会报错限流,之后就可以抗住10/s的QPS了

4.2.2 排队等待

官网:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

源码:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

SpringCloud:Sentinel实现熔断与限流(1)

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

SpringCloud:Sentinel实现熔断与限流(1)

/testA的QPS最大为1,超过的话就排队等待,等待的超时时间为20000ms。

修改一下业务代码,把线程名打印出来以验证是否排队。

SpringCloud:Sentinel实现熔断与限流(1)

测试

SpringCloud:Sentinel实现熔断与限流(1)

5.降级规则(熔断规则)

Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。
当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。

Sentinel 提供以下几种焙断策略:

  • 慢调用比例 ( SLON_ REQUEST_RATI0):选择以慢调用比例作为國值,需要设置允许的慢调用 RT (即最大的响应时间)请求的响应时间大于该值则统计为慢调用。当单位統计时长(statIntervalns) 内请求数目大于设置的最小请求数目,并旦慢调用的比例大于同值,则接下来的焙断时长内请求会自动被熔断。经过烙断时长后熔断品会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 阿T 则会再次被熔断。
  • 导常比例 (ERROR RATIO):当单位统计时长(statIntervalMs) 内请求数目大于设置的最小请求数目,并且异常的比例大于园值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态 (HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束断,否则会再次被熔断。异常比率的园值范围是 [0.0,1.0],代表 0% – 100%。
  • 异常数(ERROR_ COUNT):当单位统计时长内的异常数目超过國值之后会自动进行熔断。经过熔断时长后熔断器会进入探測恢复状态 (HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

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

官方繁琐概念(不如看例子)

老版本:

SpringCloud:Sentinel实现熔断与限流(1)

新版本:

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

实战测试

业务类中加一个rest 接口,以用于测试:

编辑熔断规则:

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

SpringCloud:Sentinel实现熔断与限流(1)

jmeter压测:

SpringCloud:Sentinel实现熔断与限流(1)

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

SpringCloud:Sentinel实现熔断与限流(1)

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

5.1.2 异常比例

概念

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

实战测试

SpringCloud:Sentinel实现熔断与限流(1)

编辑熔断规则:

1000ms统计时长内,大于5次的请求中超过80%的请求出现异常,则熔断2s。

SpringCloud:Sentinel实现熔断与限流(1)

jmeter压测

单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次;开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。断路器开启(保险丝跳闸),微服务不可用了,不再报错error而是服务降级了

SpringCloud:Sentinel实现熔断与限流(1)

停掉jemeter后过2s。报/zero错误,因为业务类中有个10/0。

5.1.3 异常数

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

实战测试
修改业务类:

SpringCloud:Sentinel实现熔断与限流(1)

编辑熔断规则:

SpringCloud:Sentinel实现熔断与限流(1)

好像有bug,虽然熔断了但是熔断时长不是我配置的5s,大约是一分钟,统计时长也不是1s,好像也是一分钟,同时没达到最小请求数,只达到3次异常就直接熔断了。虽然我用的新版本,但是逻辑好像跟老版本的一样?

正文完
 0