06、Sentinel 源码分析 之 受规则保护的资源运行

在之前的文章当中我们通过 json 文件定义规则并且读取这个规则文件通过流量规则管理器 FlowRuleManager把定义的规则加载到 FlowRuleManager 的属性 flowRules 并发安全类 AtomicReference 当中。并且通过 SentinelResourceAspect 这个切面类让类或者方法这些资源上定义了 @SentinelResource 注解具有规则保护的功能。

下面我们来看一下,当我们的资源通过 SphU#entryentry#exit 包裹 Sentinel 框架做了哪些事来保护我们的资源。

1、InitExecutor

在调用 SphU#entry(“资源名称”) 的时候,其实查看 SphU 类源码的时候它的调用逻辑如下:

public class SphU {

    public static Entry entry(String name) throws BlockException {
        return Env.sph.entry(name, EntryType.OUT, 1, OBJECTS0);
    }

	......

}

在方法内部处理当中会调用 Env 的内部静态常量 sph

public class Env {

    public static final Sph sph = new CtSph();

    static {
        // If init fails, the process will exit.
        InitExecutor.doInit();
    }

}

调用 Env#sph 这个静态属性的时候就会调用 Env 这个类中的静态代码块。InitExecutor 就会通知 SPI 机制调用 InitFunc 实现类的 init 初始化一些在资源规则保护之前的一些 Sentinel 框架的内部资源。在 Sentinel 框架中 InitFunc 的实现类如下:
在这里插入图片描述
具体功能我就不赘述了,大家如果感兴趣可以自行了解。

2、受规则保护的资源运行

下面我们来看一下受规则保护的资源在 Sentinel 的运行时序图。
在这里插入图片描述
在这个时序图里面我们可以看到受规则保护的资源的的整个运行图,当然这个时序图里面隐藏了一些细节。下面我就把这个时序图里面最核心的东西梳理出来,让大家能够很清晰的理解 Sentinel 框架的整个运行脉络。

  • 在运行之前会通过 InitExecutor 触发 InitFunc 这个 SPI 接口的初始化 Sentinel 框架内部资源的初始化。当然你也可以自定义实现 InitFunc 来初始化自己需要的资源
  • 然后就是通过调用 CtSph#lookProcessChain 构建资源被调用之前的规则拦截器链的构建。在内部会调用 SlotChainProvider#newSlotChain 通过 SPI 机制来实例化 SlotChainBuilder 的实现类 DefaultSlotChainBuilder。并且调用 DefaultSlotChainBuilder#build 再次通过 Sentinel 框架的 SPI 机制来实例化 ProcessorSlot 接口的实现类列表,通过 ProcessorSlot 接口实现类的列表构建 DefaultProcessorSlotChain 拦截器链。DefaultProcessorSlotChain 对象是单向链表,有一个当前指针 first,然后还有一个后移指针 next。
  • CtSph#entryWithPriority 会触发上面 DefaultProcessorSlotChain 这个拦截器链表的调用。也就是会调用 DefaultProcessorSlotChain#entry,首先调用 DefaultProcessorSlotChain#first 它的 first 指针,然后调用AbstractLinkedProcessorSlot#next 完成整个调用链的调用。

3、拦截器链的构建

在上面已经说过了拦截器链的构建最终是通过调用 DefaultSlotChainBuilder#build 方法来进行构建的。

public class DefaultSlotChainBuilder implements SlotChainBuilder {

    @Override
    public ProcessorSlotChain build() {
        ProcessorSlotChain chain = new DefaultProcessorSlotChain();

        // Note: the instances of ProcessorSlot should be different, since they are not stateless.
        List<ProcessorSlot> sortedSlotList = SpiLoader.loadPrototypeInstanceListSorted(ProcessorSlot.class);
        for (ProcessorSlot slot : sortedSlotList) {
            if (!(slot instanceof AbstractLinkedProcessorSlot)) {
                RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain");
                continue;
            }

            chain.addLast((AbstractLinkedProcessorSlot<?>) slot);
        }

        return chain;
    }
}

在这里它会找到在 resources/META-INF/servicescom.alibaba.csp.sentinel.slotchain.ProcessorSlot 命名的文件,在这个文件的内部会有```ProcessorSlot`` 的实现类列表。

# Sentinel default ProcessorSlots
com.alibaba.csp.sentinel.slots.nodeselector.NodeSelectorSlot
com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot
com.alibaba.csp.sentinel.slots.logger.LogSlot
com.alibaba.csp.sentinel.slots.statistic.StatisticSlot
com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot
com.alibaba.csp.sentinel.slots.system.SystemSlot
com.alibaba.csp.sentinel.slots.block.flow.FlowSlot
com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot

上面就是在 sentinel-core 项目中 resources/META-INF/services 目录下 com.alibaba.csp.sentinel.slotchain.ProcessorSlot 命名的文件中的 ProcessorSlot 的实现类列表。

最终会构建成以下的调用链:

NodeSelectorSlot => ClusterBuilderSlot => LogSlot => 
StatisticSlot => AuthoritySlot => SystemSlot => FlowSlot => DegradeSlot

以上的拦截器就是对受保护资源的功能增强,下面是各个节点的能够增强的功能:

  • NodeSelectorSlot:负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
  • ClusterBuilderSlot:则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
  • LogSlot:则负责 BlockException 异常日志的打印
  • StatisticSlot:则用于记录、统计不同纬度的 runtime 指标监控信息;
  • FlowSlot:则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
  • AuthoritySlot:则根据配置的黑白名单和调用来源信息,来做黑白名单控制;
  • DegradeSlot:则通过统计信息以及预设的规则,来做熔断降级;
  • SystemSlot:则通过系统的状态,例如 load1 等,来控制总的入口流量;
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页