源码分析 Sentinel DegradeSlot 熔断实现原理

yoursoft
发布于 2023-2-20 17:12
浏览
0收藏

1、DegradeSlot 概述


Sentinel 中的熔断实现类为 DegradeSlot。DegradeSlot 的类定义如下图所示:


源码分析 Sentinel DegradeSlot 熔断实现原理-开源基础软件社区


由此可见,熔断主要实现逻辑定义在 DegradeRuleManager 的 checkDegrade 方法中。

DegradeRuleManager#checkDegrade


源码分析 Sentinel DegradeSlot 熔断实现原理-开源基础软件社区


代码@1:首先从 degradeRules 熔断规则缓存中获取资源的熔断规则。

代码@2:遍历熔断规则列表。

代码@3:调用熔断规则 DegradeRule 的  passCheck,如果该方法返回 false,则表示需要熔断,则抛出 DegradeException 异常。

即实现熔断的核心逻辑在 DegradeRule 中。

2、DegradeRule 详解


在介绍 DegradeRule 之前我们先来看看 sentinel-dashboard 关于熔断降级规则的配置:


源码分析 Sentinel DegradeSlot 熔断实现原理-开源基础软件社区


我们可以直观的得知,降级规则可以根据如下三个指标进行设置:RT(响应时间)、异常比例、异常数。

2.1 DegradeRule 类图

源码分析 Sentinel DegradeSlot 熔断实现原理-开源基础软件社区


  • double count上面配置规则中对应的配置值,例如当降级策略为RT时,表示设置的响应时间值,其他类似。
  • int timeWindow降级发生后多久进行恢复,即结束降级,单位为毫秒。
  • int grade降级策略,可以选值如下:1)DEGRADE_GRADE_RT响应时间。2)DEGRADE_GRADE_EXCEPTION_RATIO异常数比例。3)DEGRADE_GRADE_EXCEPTION_COUNT异常数量。
  • int rtSlowRequestAmount触发 RT 响应熔断出现的最小连续慢响应请求数量。
  • int minRequestAmount触发熔断最小的请求数量。

2.2 passCheck方法详解

根据当前请求的情况触发熔断的判断逻辑由 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:降级策略为基于响应时间的判断规则,其核心实现关键点:

  • 首先获取节点的平均响应时间。
  • 如果当前平均响应时间小于阔值,则放行,并重置 passCount 为 0。
  • 如果当前平均响应时间大于阔值,但连续次数小于 rtSlowRequestAmount,依然放行,只有当连续 rtSlowRequestAmount 次响应慢才会触发降级。

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:降级策略为根据异常比例,其判断规则核心如下:

  • 分别获取成功QPS,异常QPS,总TPS。
  • 如果当前总 QPS 小于 minRequestAmount,则直接返回成功,表示暂不进行熔断规则判断。
  • 如果成功数小于异常数并且异常数量小于 minRequestAmount,则返回true,表示暂不进熔断规则的判断。
  • 如果异常比例小于阔值,同样返回 true,表示暂不进熔断规则的判断。

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 基于集群的限流策略。

好了,亲爱的读者朋友,以上就是本文的全部内容了,Sentinel 熔断实现是不是超简单,Get到了吗?原创不易,莫要白票,请你为本文点个【赞】吧,这将是我写作更多优质文章的最强动力。




文章转载自公众号:  中间件兴趣圈


分类
标签
已于2023-2-20 17:12:08修改
收藏
回复
举报
回复
    相关推荐