sentinel熔断降级
熔断处理
1、工作原理
熔断降级是解决雪崩问题的重要手段。其思路是由断路器统计服务调用的异常比例、异常数、慢请求比例,如果超出阈值则会熔断该服务。即拦截访问该服务的一切请求;而当服务恢复时,断路器会放行访问该服务的请求。
Sentinel 熔断降级基于熔断器模式 (circuit breaker pattern) 实现。熔断器内部维护了一个熔断器的状态机,状态机的转换关系如下图所示:
状态机包括三个状态:
1、closed(初始状态):关闭状态,断路器放行所有请求,并开始统计异常比例、异常数、慢请求比例。超过阈值则切换到open状态
2、Open 状态:断开状态,熔断器处于开启状态,对资源的访问会被切断。
3、Half-Open 状态:半开状态,该状态下除了探测流量,其余对资源的访问也会被切断。探测流量指熔断器处于半开状态时,会周期性的允许一定数目的探测请求通过,如果探测请求能够正常的返回,代表探测成功,此时熔断器会重置状态到 Closed 状态,结束熔断;如果探测失败,则回滚到 Open 状态
2、 断路器熔断判断策分类
2.1、慢调用比例
慢调用: 业务的响应时长(RT,response time)大于指定时长的请求认定为慢调用请求。sentinel会统计指定时间内,请求数量超过设定的最小数量的请求并且慢调用比例的比例。如果慢调用比例大于设定的阈值,则触发熔断。
• 触发逻辑:
• 在统计窗口内,请求总数 ≥ 最小请求数
• 且慢调用(比如耗时 > 500ms)的比例 ≥ 阈值
• 👉 触发熔断
案例演示
需求:给 query的查询用户接口设置降级规则,慢调用的RT阈值为50ms,统计时间为1秒,最小请求数量为3,失败阈值比例为0.4,熔断时长为5s
@SentinelResource("hot")
@GetMapping("query")
public String query() {
System.out.println("查询用户");
// 延长时间做演示
try {
Thread.sleep(60);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "查询用户成功" ;
}
设置熔断规则
- 含义:RT超过50ms的调用是慢调用,统计最近1000ms内的请求,如果请求量超过3次,并且慢调用比例大于0.4,则触发熔断,熔断时长为5秒。然后进入half-open状态,放行一次请求做测试。
测试看结果
没有达到熔断规则
熔断规则条件生效,触发熔断
com.alibaba.csp.sentinel.slots.block.degrade.DegradeException: null
- Sentinel 抛出了一个 DegradeException,表示该接口已经被降级了
过5秒后,发出探测请求,成功后回滚熔断器为关闭
2.2异常比例
• 触发逻辑:
• 在统计窗口内,请求总数 ≥ 最小请求数
• 且异常数 / 总请求数 ≥ 阈值
• 👉 触发熔断
在接口中手动抛出异常, 进行测试
比例阈值 0.4 表示异常比例超过 40% 就触发熔断。
熔断时长 10s 一旦触发熔断,该接口将会在 10 秒内 被快速失败(直接抛 DegradeException),请求不会进入真实逻辑。
最小请求数 3 在统计周期内,至少有 3 次请求 才进行异常比例的判断(少于 3 次请求就不判断,防止误判)。
统计时长 1000ms 统计周期是 1 秒,也就是每 1 秒统计一次请求和异常的比例
✅ 如果某 1 秒内:
• 请求了 5 次
• 出错了 3 次
• 异常比例 = 3 / 5 = 60%,大于 40%,满足触发条件
• 👉 熔断触发,后续的请求在 10 秒内都会直接失败(不会进入业务逻辑)
❌ 如果某 1 秒内:
• 请求了 2 次
• 出错了 2 次(异常比例是 100%)
• 但因为少于 3 次请求,不触发熔断(保护机制)
2.3异常数
• 触发逻辑:
• 在统计窗口内,请求总数 ≥ 最小请求数
• 且异常数 ≥ 阈值
• 👉 触发熔断
异常数 2 在统计时间窗口内,异常次数 ≥ 2 就触发熔断。
熔断时长 10s 熔断后会维持 10 秒,这期间对该接口的请求会被直接拒绝(抛 DegradeException)。
最小请求数 3 必须在统计周期内请求次数 ≥ 3 才会判断是否熔断,避免低频触发。
统计时长 1000ms 统计时间窗口是 1 秒,也就是说,每秒钟统计一次异常次数。
✅ 如果 1 秒内发生如下:
• 接口 /selectByUserId/{userId} 请求了 5 次
• 其中有 3 次抛出了异常(比如运行时异常、数据库异常等)
• 因为异常数 ≥ 2 且请求数 ≥ 3 ⇒ 满足熔断条件 ⇒ 触发熔断
• 后续的请求,在接下来的 10 秒内 都会被直接拒绝(返回 Sentinel 抛出的 DegradeException)
❌ 如果 1 秒内只请求了 2 次:
• 不管有没有异常,因为请求总数小于 3,不判断是否熔断