Sentinel熔断和限流

Sentinel熔断和限流

一、sentinel

官网:

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

下载:

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控制台

1、sentinel组件由2部分组成

  • 后台
  • 前台8080

2、安装步骤
下载
https://github.com/alibaba/Sentinel/releases
下载到本地sentinel-dashboard-1.7.0.jar

运行命令
前提:
java8环境OK
8080端口不能被占用
命令:

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,否则无效

直接(默认)

配置及说明:

关联:


postman模拟密集访问testB:

流控预热:

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

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

排队等待:

匀速排队,让请求以均匀的速度通过,阀值类型必须设成QPS,否则无效。
设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。

匀速排队( Ruleconstant.CONTROL BEHAVIOR RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。详细文档可以参考 流星控制-匀速器模式,具体的例子可以参见 PaceFlowDemo。

这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接本来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒真接拒绝多余的请求。

测试:

五、降级规则


RT(平均响应时间,秒级)
平均响应时间 超出阈值 且 在时间窗口内通过的请求>=5,两个条件同时满足后触发降级
窗口期过后关闭断路器。
RT最大4900(更大的需要通过-Dcsp,sentinel.statistic.max.rt=XXXX才能生效)

异常比列(秒级)
QPS >=5 且异常比例(秒级统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。
异常数(分钟级)
异常数(分钟统计)超过阈值时,触发降级;时间窗口结束后,关闭降级。

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

复习Hystrix:

降级策略实战--RT
平均响应时间(DEGRADE GRADE RT):当 1s 内持续进入5个请求,对应时刻的平均响应时间(秒级)均超过阈值(count ,以 ms 为单位),那么在接下的时间窗口(DegradeRule中的timewindow ,以s为单位)之内,对这个方法的调用都会自动地熔断(抛出DegradeException)。注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作4900 ms,若需要变更此上限可以通过启动配置项-Dcsp.sentinel.statistic.max.rt=xxx来配置。

配置:

结论:

异常比例:
异常比例(DEGRADE GRADE EXCEPTION RATIO ):当资源的每秒请求量>=5,并且每秒异常总数占通过量的比值超过阈值(DegradeRu1e中的count )之后,资源进入降级状态,即在接下的时间窗口(DegradeRu1e 中的 timewindow ,以s为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是[0.8,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而是服务降级了。

异常数:
异常数(DEGRADE GRADE EXCEPTION COUNT ):当资源近1分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若timewindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。

配置:

六、热点key限流

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

配置:

参数例外项:

添加异常:
@SentinelResource
处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;
RuntimeException
int age = 10/0,这个是java运行时报出的运行时异常RunTimeException,@SentinelResource不管。
总结:
@SentinelResource主管配置出错,运行出错该走异常走异常。

七、系统规则

各项配置参数说明:
系统保护规则是从应用级别的入口流量进行控制,从单台机器的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 达到阈值即触发系统保护。

八、@SentinelResorce

按资源名称限流+后续处理
配置步骤:

按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的异常。

九、服务熔断功能

熔断框架比较:

评论

暂无

添加新评论