Sentinel 中的熔断实现类为 DegradeSlot。DegradeSlot 的类定义如下图所示:
由此可见,熔断主要实现逻辑定义在 DegradeRuleManager 的 checkDegrade 方法中。 DegradeRuleManager#checkDegrade
代码@1:首先从 degradeRules 熔断规则缓存中获取资源的熔断规则。
代码@2:遍历熔断规则列表。
代码@3:调用熔断规则 DegradeRule 的 passCheck,如果该方法返回 false,则表示需要熔断,则抛出 DegradeException 异常。
即实现熔断的核心逻辑在 DegradeRule 中。
在介绍 DegradeRule 之前我们先来看看 sentinel-dashboard 关于熔断降级规则的配置:
我们可以直观的得知,降级规则可以根据如下三个指标进行设置:RT(响应时间)、异常比例、异常数。
根据当前请求的情况触发熔断的判断逻辑由 passCheck 方法实现。在介绍这个方法之前,我们根据该方法调用上下文得知,该方法返回 false,则触发熔断。 DegradeRule#passCheck
if (cut.get()) {
return false;
}
Step1:如果当前正在处于熔断降级中,将直接返回 false,请求将被限流。
DegradeRule#passCheck
ClusterNode clusterNode = ClusterBuilderSlot.getClusterNode(this.getResource());
if (clusterNode == null) {
return true;
}
Step2:根据资源名称获得对应的集群类节点,有关集群限流将在后续文章中详细介绍。
DegradeRule#passCheck
if (grade == RuleConstant.DEGRADE_GRADE_RT) {
double rt = clusterNode.avgRt();
if (rt < this.count) {
passCount.set(0);
return true;
}
if (passCount.incrementAndGet() < rtSlowRequestAmount) {
return true;
}
}
step3:降级策略为基于响应时间的判断规则,其核心实现关键点:
DegradeRule#passCheck
} else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) {
double exception = clusterNode.exceptionQps();
double success = clusterNode.successQps();
double total = clusterNode.totalQps();
if (total < minRequestAmount) {
return true;
}
double realSuccess = success - exception;
if (realSuccess <= 0 && exception < minRequestAmount) {
return true;
}
if (exception / success < count) {
return true;
}
}
Step4:降级策略为根据异常比例,其判断规则核心如下:
DegradeRule#passCheck
else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT) {
double exception = clusterNode.totalException();
if (exception < count) {
return true;
}
}
Step5:降级策略为根据异常数量,这策略只是简单的判断错误数量即可。
DegradeRule#passCheck
if (cut.compareAndSet(false, true)) {
ResetTask resetTask = new ResetTask(this);
pool.schedule(resetTask, timeWindow, TimeUnit.SECONDS);
}
Step6:如果符合触发熔断的规则,则原子更新 cut,并且开启一个调度任务,在指定时间过后进行降级恢复。
Sentinel 的熔断机制实现比较简单,就介绍到这了,下一篇将介绍 Sentinel 基于集群的限流策略。