Sentinel 之 原理

架构图解析

若要读懂Sentinel源码,则必须要搞明白官方给出的Sentinel的架构图。

Sentinel 之 原理

Sentinel的核心骨架是 ProcessorSlotChain。其将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能组合在一起(限流、降级、系统保护)。系统会为每个资源创建一套SlotChain。

 

SPI机制

Sentinel槽链中各Slot的执行顺序是固定好的。但并不是绝对不能改变的。Sentinel将ProcessorSlot 作为 SPI 接口进行扩展,使得 SlotChain 具备了扩展能力。用户可以自定义Slot并编排Slot 间的顺序。

Sentinel 之 原理

 

Slot简介

1、NodeSelectorSlot

负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降。

2、ClusterBuilderSlot

用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count,Block count,Exception count 等等,这些信息将用作为多维度限流,降级的依据。简单来说,就是用于构建ClusterNode。

3、StatisticSlot

用于记录、统计不同纬度的 runtime 指标监控信息。

4、ParamFlowSlot

对应控制台的:热点流控

5、FlowSlot

用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制。对应控制台的:流控规则

6、AuthoritySlot

根据配置的黑白名单和调用来源信息,来做黑白名单控制。对应控制台的:授权规则

7、DegradeSlot

通过统计信息以及预设的规则,来做熔断降级。对应控制台的:降级规则

8、SystemSlot

通过系统的状态,例如 load1 等,来控制总的入口流量。对应控制台:系统规则

 

Context介绍

Context是对资源操作的上下文,每个资源操作必须属于一个Context。如果代码中没有指定Context,则会创建一个name为sentinel_default_context的默认Context。一个Context生命周期中可以包含多个资源操作。Context生命周期中的最后一个资源在exit()时会清理该Conetxt,这也就意味着这个Context 生命周期结束了。

Node 间的关系

Sentinel 之 原理

Root 表示一个应用,不如一个项目模块;

1、Node:用于完成数据统计的接口

2、StatisticNode:统计节点,是Node接口的实现类,用于完成数据统计

3、EntranceNode:入口节点,一个Context会有一个入口节点,用于统计当前Context的总体流量数据

4、DefaultNode:默认节点,用于统计一个资源在当前Context中的流量数据

5、ClusterNode:集群节点,用于统计一个资源在所有Context中的总体流量数据

/**
 * 限流的过程伪代码示例
 */
public void testMethod() {
    // 创建一个来自于appA访问的Context,
    // 显示的指定名称的创建一个 上下文对象 Context,entranceOne为Context的name,appA为来源,
    ContextUtil.enter("entranceOne", "appA");
    // Entry就是一个资源操作对象
    Entry resource1 = null;
    Entry resource2 = null;
    try {
        // 获取资源resource1的entry
        resource1 = SphU.entry("resource1");
        // 代码能走到这里,说明当前对资源resource1的请求通过了流控
        // 对资源resource1的相关业务处理。。。
        // 获取资源resource2的entry
        resource2 = SphU.entry("resource2");
        // 代码能走到这里,说明当前对资源resource2的请求通过了流控
        // 对资源resource2的相关业务处理。。。
    } catch (BlockException e) {
        // 代码能走到这里,说明请求被限流,
        // 这里执行降级处理
    } finally {
        if (resource1 != null) {
            resource1.exit();
        }
        if (resource2 != null) {
            resource2.exit();
        }
    }
    // 释放Context
    ContextUtil.exit();
}

 

>>>>>>>>>>>  接下一篇学习:https://www.cnblogs.com/Alay/p/15488137.html <<<<<<<<<<<<

上一篇:sentinel自定义扩展


下一篇:redis集群模式跟哨兵模式区别