目录
1.Sentinel系统规则
Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
(即在系统外面就对系统进行一次限流,里面再根据限流规则进行限流)
系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。
系统规则支持以下的模式:
- Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
- CPU 使用率:当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
- 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
- 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
(因其总控功能会导致整个系统的瘫痪,固慎用)
2.SentinelResource配置
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。其包含以下属性:
- value:资源名称,不能为空
- entryType:entry 类型,可选项(默认为 EntryType.OUT)
- blockHandler / blockHandlerClass,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- fallback /fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
- fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- defaultFallback:默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
- 返回值类型必须与原函数返回值类型一致;
- 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
- defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
案例:
在控制类添加如下代码进行测试:
启动8401后,新增流控规则:
测试:1秒钟点击1下,OK;超过上述,疯狂点击,返回了自己定义的限流处理信息,限流发生。
符合流控规则。
此时关闭问服务8401 -> Sentinel控制台,流控规则消失了——>流控规则临时。
通过访问的URL来限流,会返回Sentinel自带默认的限流处理信息:
测试结果相同。
上面兜底方案面临的问题:
- 系统默认的,没有体现我们自己的业务要求。
- 依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观。
- 每个业务方法都添加—个兜底的,那代码膨胀加剧。
- 全局统—的处理方法没有体现。
1.我们可以创建一个自定义限流处理类 - 创建CustomerBlockHandler类用于自定义限流处理逻辑。
(指定哪个类里面的哪个方法兜底)
测试结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/cbb9be0010c2eceacf8d2cf73c503cb5.png)
3.Sentinel服务熔断Ribbon
- 启动nacos和sentinel
- 提供者9003/9004
- 消费者84
payment9003/9004建立过程与前面类似,具体不再阐述:
(yml文件中入驻进nacos进行服务注册)
order84也与前面Robbin负载均衡类似(建立config类实现restTemplate的使用):
此处在控制类进行服务熔断(无配置情况下):
测试访问id=4,返回error页面(不太友好):
下面我们对fallback进行配置,fallback只负责业务异常:
再次测试,兜底方法成功返回:
下面我们对blockHandler进行配置,blockHandler只负责sentinel控制台配置违规:
对该fallback新增限流规则:
测试,第一次访问,返回error页面(因blockHandler只负责sentinel控制台配置违规,不负责业务异常);1s内第二次访问超过,超过阈值1,返回blockHandler。
fallback和blockHandler都配置:
结果返回:
结论:fallback和blockHandler都配置,同时满足两种异常,使用blockHandler方法。
exceptionsToIgnore,忽略指定异常,即这些异常不用兜底方法处理。
4.Sentinel服务熔断OpenFeign
首先,需要激活sentinel对Feign的支持:
编写service类调用feign来调用payment微服务:
编写控制类来调用service类,进行测试:
测试84调用9003,此时故意关闭9003微服务提供者,84消费侧自动降级,不会被耗死。
(此处与hystrix与openfeign的结合一致)