一、sentinel
官网:
https://github.com/alibaba/Sentinel
https://github.com/alibaba/Sentinel/wiki
下载:
https://github.com/alibaba/Sentinel/releases
文档:
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_sentinel
服务使用中的各种问题:
- 服务雪崩
- 服务降级
- 服务熔断
- 服务限流
二、安装Sentinel控制台
2.1、sentinel组件由2部分组成
- 后台
- 前台8080
2、安装步骤
下载:https://github.com/alibaba/Sentinel/releases
下载到本地 sentinel-dashboard-1.7.0.jar
。
运行命令
java -jar sentinel-dashboard-1.7.0.jar
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
访问 sentinel 管理界面:
http://localhost:8080
登录账号密码均为sentinel
。
Sentinel 分为两个部分:
核心库(Java客户端)
不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo /Spring Cloud 等框架也有较好的支持。控制台(Dashboard)
基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
三、初始化演示工程
控制台显示效果:
四、流控规则
进一步解释说明:
资源名
:唯一名称,默认请求路径。针对来源
:Sentine可以针对调用者进行限流,填写微服务名,默认default(不区分来源)。阈值类型 / 单机阈值
:QPS (每秒钟的请求数量)
:当调用该api的QPS达到阈值的时候,进行限流。线程数
:当调用该api的线程数达到阈值的时候,进行限流。
是否集群
:不需要集群。流控模式
:直接
:api达到限流条件时,直接限流。关联
:当关联的资源达到阈值时,就限流自己。链路
:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流) 【api级别的针对来源】。
流控效果
:快速失败
:直接失败,抛异常。Warm Up
:根据 codeFactor(冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值。排队等待
:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为 QPS,否则无效。
4.1、直接模式(默认)
配置及说明:
4.2、关联模式:
postman 模拟密集访问 testB:
4.3、链路模式:
只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值,如果超过阈值对从该链路请求进行限流。
配置方法:
如果只希望统计从 /api/user/query
进入到 users
的请求,并进行限流操作,则可以这样配置:
// 在UserService中添加一个queryUsers方法,不用实现业务
public void queryUsers(){
System.err.println("查询用户");
}
// 在上述Controller中,添加两个端点(请求方法),在这两个端点中分别调用UserService中的queryUsers方法
@GetMapping(value = "/save")
public String save() {
userService.queryUsers();
System.out.println("保存用户");
return "订单保存成功" ;
}
@GetMapping(value = "/query")
public String query() {
userService.queryUsers();
System.out.println("查询用户");
return "查询用户成功" ;
}
// 通过@SentinelResource标记UserService中的queryUsers方法为一个sentinel监控的资源(默认情况下,sentinel只监控controller方法)
@SentinelResource("users")
public void queryUsers(){
System.err.println("查询用户");
}
// 更改application.yml文件中的sentinel配置
// 链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入spring mvc的所有请求设置同一个root资源,会导致链路模式失效。因此需要关闭这种资源整合。
spring:
cloud:
sentinel:
web-context-unify: false # 关闭context整合
4.4、流控预热:
Warm Up (RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。详细文档可以参考流量控制-Warm Up 文档,具体的例子可以参见:
WarmUpFlowDemo
。通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:
Warmup 配置
:
默认 coldFactor
为 3,即请求QPS从 (threshold/3) 开始,经多少预热时长才逐渐升至设定的 QPS 阈值。
案例,阀值为 10+
预热时长设置 5
秒。
系统初始化的阀值为 10/3
约等于 3
,即阀值刚开始为 3
。然后过了 5
秒后阀值才慢慢升高恢复到 10
。
应用场景:
如:秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是把为了保护系统,可慢慢的把流量放进来,慢慢的把阀值增长到设置的阀值。
4.5、排队等待:
匀速排队,让请求以均匀的速度通过,阀值类型必须设成 QPS,否则无效。
设置含义:/testA
每秒 1 次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
匀速排队( Ruleconstant.CONTROL BEHAVIOR RATE_LIMITER)
方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考流量控制-匀速器模式,具体的例子可以参见 PaceFlowDemo
。
这种方式主要用于处理间隔性突发的流量,例如消息队列
。想象一下这样的场景,在某一秒有大量的请求到来,而接本来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒真接拒绝多余的请求。
五、降级规则
5.1、RT(平均响应时间,秒级)
平均响应时间出阈值且在时间窗口内通过的请求 >=5,两个条件同时满足后触发降级窗口期过后关闭断路器。
RT 最大 4900 (更大的需要通过-Dcsp,sentinel.statistic.max.rt=XXXX
才能生效)
5.2、异常比列(秒级)
QPS >=5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。
5.3、异常数(分钟级)
异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。
进一步说明:
Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。
当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException
)。
复习Hystrix:
5.4、降级策略
平均响应时间(DEGRADE GRADE RT)
:当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(count,以 ms 为单位),那么在接下的时间窗口(DegradeRule中的timewindow ,以s为单位)之内,对这个方法的调用都会自动地熔断(抛出DegradeException
)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作4900 ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx
来配置。
配置:
结论:
5.5、异常比例
异常比例(DEGRADE GRADE EXCEPTION RATIO )
:当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值(DegradeRu1e中的count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRu1e 中的 timewindow ,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0,1.0],代表 0%-100%。
配置:
jmeter:
结论:
按照上述配置,单独访问一次,必然来一次报错一次(int age = 10/0),调一次错一次;
异常比例(DEGRADE_GRADE_EXCEPTION_RATIO):当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timewindow ,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.0, 1.0] ,代表0%-100%。
开启jmeter后,直接高并发发送请求,多次调用达到我们的配置条件了。
断路器开启(保险丝跳闸),微服务不可用了,不再报错 error 而是服务降级了。
5.6、异常数
异常数(DEGRADE GRADE EXCEPTION COUNT)
:当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timewindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。
配置:
六、热点key限流
6.1、兜底方法
分为系统默认
和客户自定义
,两种:
之前的case,限流出问题后,都是用sentinel系统默认的提示: Blocked by Sentinel (flow limiting)
我们能不能自定?类似hystrix,某个方法出问题了,就找对应的兜底降级方法?
结论:
从 HystrixCommand
到 @SentinelResource
。
6.2、配置
参数例外项:
添加异常:
@SentinelResource
处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;
RuntimeException
int age = 10/0,这个是java运行时报出的运行时异常 RunTimeException
,@SentinelResource
不管。
总结:
@SentinelResource
主管配置出错,运行出错该走异常走异常。
七、系统规则
各项配置参数说明:
系统保护规则是从应用级别的入口流量进行控制,从单台机器的load、CPU 使用率、平均RT、入口QPS和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN
) ,比如Web服务或Dubbo 服务端接收的请求,都属于入口流量。
系统规则支持以下的模式:
Load自适应(仅对Linux/Unix-like机器生效)
:系统的 load 作为启发指标,进行自适应系统保护。当系统 load 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR阶段) 。系统容量由系统的maxQps * minRt
估算得出。设定参考值一般是CPU cores * 2.5
。CPU usage (1.5.0+版本)
:当系统CPU使用率超过阈值即触发系统保护(取值范围0.0-1.0),比较灵敏。平均RT
:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。并发线程数
:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。入口QPS
:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
八、@SentinelResorce
8.1、按资源名称限流 + 后续处理
配置步骤:
8.2、按Url地址限流 + 后续处理
配置:
上面兜底方法面临的问题:
- 系统默认的,没有体现我们自己的业务要求。
- 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
- 每个业务方法都添加一个兜底的,那代码膨胀加剧。
- 全局统一的处理方法没有体现。
更多注解属性说明:
- value:作用指定资源名称,必填。
- entryType:entry类型,标记流量的方向,指明是出口流量,还是入口流量;取值
IN/OUT
,默认是OUT
。非必填。 - blockHandler:处理
BlockException
的函数名称,函数要求为必须是public
返回类型与原方法一致参数类型需要和原方法相匹配,并在最后加上BlockException
类型的参数默认需和原方法在同一个类中,如果希望使用其他类的函数,可配置blockHandlerClass
,并指定blockHandlerClass
里面的方法。 - blockHandlerClass:存放
blockHandler
的类。对应的处理函数必须static
修饰,否则无法解析。函数要求为:必须是public 返回类型与原方法一致参数类型需要和原方法相匹配,并在最后加上BlockException
类型的参数。 - fallback:用于在抛出异常的时候提供
fallback
处理逻辑。fallback
函数可以针对所有类型的异常(除了execptionsToIgnore
里面排除掉的异常类型)进行处理,函数要求为:返回类型与原方法一致 参数类型需要和原方法相匹配,Sentinel 1.6
版本之后,也可在方法最后加上Throwable
类型的参数,默认需和原方法在同一个类中,若希望使用其他类的函数,可配置fallbackClass
,并指定fallbackClass
里面的方法。 - fallbackClass:存放
fallback
的类。对应的处理函数必须static
修饰,否则无法解析,其他要求:同fallback。 - defaultFallback:用于通用的
fallback
逻辑。默认fallback
函数可以针对所有类型的异常(除了exceptionsToIgnore
里面排除掉的异常类型)进行处理。若同时配置了fallback
和defaultFallback
,以fallback
为准。函数要求:返回类型与原方法一致 方法参数列表为空,或者有一个Throwable
类型的参数 默认需要和原方法在同一个类中,若希望使用其他类的函数,可配置fallbackclass
,并指定fallbackClass
里面的方法。 - exceptionsToIgnore:指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入
fallback
逻辑,而是原样抛出。 - exceptionsToTrace:需要
trace
的异常。
九、服务熔断功能
熔断框架比较:
参考:
Sentinel简单使用
评论