熔断降级
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException)。
降级策略
- 平均响应时间 (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,并且每秒异常总数占通过量的比值超过阈值(DegradeRule 中的 count)之后,资源进入降级状态,即在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
- 异常数 (DEGRADE_GRADE_EXCEPTION_COUNT): 当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能再进入熔断状态。
RT(平均响应时间,秒级):
- 平均响应时间
超出阈值
且在时间窗口内通过的请求大于5
两个条件同时满足后触发降级 - 窗口期过后关闭断路器
- RT最大4900(更大需要通过-Dcsp.sentinel.statistic.max.rt=xxx才能生效)
异常比例(秒级):
QPS >= 5
且异常比例(秒级统计)超过阈值时
,触发降级;- 时间窗口结束后,关闭降级
异常数(分钟级):
异常数(分钟统计)超过阈值时
,触发降级- 时间窗口结束后,关闭降级
Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。
当资源降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出DegradeException)。
注意:
Sentinel的断路器是没有半开状态的。
半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。
降级规则
RT
Controller:
@GetMapping("/testD")
public String testD() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("testD 测试RT");
return "***********testD";
}
测试:JMeter
结果如下:
一秒10个线程访问testD(大于5个),我么希望200毫秒处理完本次任务,如果超过200毫秒还没处理完,在未来的1秒时间窗口内,断路器打开,微服务不可用,保险丝跳闸断电了。
异常比例
//测试异常比例
@GetMapping("/testE")
public String testE() {
log.info("testE 测试异常比例");
int age = 10 / 0;
return "********testE";
}
测试:正常访问
JMeter:
结果:
QPS达到5,且异常比例达到我们设置20%(实际为100%),断路器开启,服务降级。
单独访问一次,必然访问一次报错一次。开启jmeter后,直接高并发发送请求,多次调用达到配置条件。断路器开启,微服务不可用了,就不再报错而是服务降级了。
异常数
//测试异常数
@GetMapping("/testF")
public String testF() {
log.info("testF 测试异常比例");
int age = 10 / 0;
return "********testF";
}
测试:正常访问
JMeter
结果:
1分钟内错误数达到6个,断路器开启,微服务降级。
此时,再次访问testF,会失败:
需要等待61秒窗口期后才可以。