sentinel 基本原理

1.整体设计

sentinel的整体设计比较简单.sentinel把提供的每个功能都封装成一个slot,然后通过一个slotchain(责任链模式)把所有的功能串联起来,从而将不同的功能组合起来.sentinel的功能又分为统计功能和面向用户的限流,熔断降级等功能.sentinel的统计功能是面向用户功能的基础,sentinel通过统计信息和用户配置的rule来实现用户功能.所有的统计信息都被封装到一个一个的StatisticNode中.而用户配置的信息保存在格式的Rule中(FlowRule,DegradRule等).sentinel的整体框架如下.

 

 

 

2.核心类

2.1 Entry

每一次资源调用都会创建一个 EntryEntry 包含了资源名、curNode(当前统计节点)、originNode(来源统计节点)等信息。

CtEntry 为普通的 Entry,在调用 SphU.entry(xxx) 的时候创建。特性:Linked entry within current context(内部维护着 parent 和 child

需要注意的一点:CtEntry 构造函数中会做调用链的变换,即将当前 Entry 接到传入 Context 的调用链路上(setUpEntryFor)。

资源调用结束时需要 entry.exit()。exit 操作会过一遍 slot chain exit,恢复调用栈,exit context 然后清空 entry 中的 context 防止重复调用。

2.2 Context

Context 代表调用链路上下文,贯穿一次调用链路中的所有 Entry。Context 维持着入口节点(entranceNode)、本次调用链路的 curNode、调用来源(origin)等信息。Context 名称即为调用链路入口名称。

Context可以在资源调用之前手动通过ContextUtil.enter(name,origin)创建,name为当前context的名称,origin为调用方名称,当配置了调用方限流的时候会用到.在创建Context的时候会校验打当前Context对应的name的EntranceNode是否被创建,如果没有创建则会先创建EnranceNode.所有同名的Context会共享一个EnranceNode,这个是为了调用链路限流的时候使用.如果不手动创建Context则在调用了SphU.entry()方法之后会自动调用ContextUtil创建一个Context,和手动创建效果一样.

Context 维持的方式:通过 ThreadLocal 传递,只有在入口 enter 的时候生效。由于 Context 是通过 ThreadLocal 传递的,因此对于异步调用链路,线程切换的时候会丢掉 Context,因此需要手动通过 ContextUtil.runOnContext(context, f) 来变换 context。

2.3 Node

Sentinel 里面的各种种类的统计节点:

    • StatisticNode:最为基础的统计节点,包含秒级和分钟级两个滑动窗口结构。具体sentinel滑动窗口的实现后面再讲.
    • DefaultNode:链路节点,用于统计调用链路上某个资源的数据,维持树状结构。继承自StatisticNode,并且同一个资源的DefaultNode共同持有一个统统的ClusterNode,这个是为了方便统计该资源全局的统计信息.DefaultNode创建的维度是resource*context,并且所有的DefaultNode都保存在NodeSelectSlot的map中,同一个resouce和context的时候会从map中获取,该节点的统计信息主要使用在根据调用链路限流的时候.
    • ClusterNode:簇点,用于统计每个资源全局的数据(不区分调用链路),继承自StatisticNode.ClusterNode也存放该资源的按来源区分的调用数据,并且把数据保存在Map<String,StatisticNode> originCountMap中.特别的,Constants.ENTRY_NODE节点中用于统计全局的入口资源数据.创建维度为resource.数据来源节点的创建维度为 resouce*origin
    • EntranceNode:入口节点,特殊的链路节点,对应某个 Context 入口的所有调用数据,创建维度为resource。Constants.ROOT 节点也是入口节点。

2.4 Slot

Slot中主要定义sentinel的功能,sentinel中默认提供了以下Slot

    • NodeSelectorSlot:主要用来创建DefaultNode节点,为后面的统计信息做准备.
    • ClusterBuilderSlot:主要用来创建每个资源的ClusterNode,并且把ClusterNode保存在ClusterBuilderSlot的静态属性ClusterNodeMap中.
    • LogSlot:主要作用为当sentinel通过各种规则拒绝了当前请求之后记录资源名称和限流信息.
    • StatisticSlot:记录当前资源的统计信息,包括QPS,线程数,通过请求数量,拒绝请求数量等所有的统计信息.
    • AuthoritySlot:根据配置的黑白名单规则校验当前请求是否符合规则,否则抛出AuthorityException.详细过程后面再讲.
    • SystemSlot:根据系统当前负载,调用SystemRuleManager根据用户配置的系统负载规则校验当前请求是否可以通过,如果不能通过则抛出SystemBlockException
    • FlowSlot:通过调用FlowRuleChecker和用户配置的限流规则校验当前请求是否符合规则,如果不符合则抛出FlowException,具体过程后面讲.
    • DegradeSlot:根据用户配置的熔断规则判断当前资源是否需要熔断,如果需要则抛出DegradeException

2.5 ProcessSlotChain

Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起.processSlotChain也实现了AbstractLinkedProcessorSlot,在默认的DefaultProcessSlotChain中定义了first和end两个AbstractLinkedProcessSlot,当调用ProcessSlotChain的entry方法的时候ProcessSlotChain会调用fireEntry方法,而fireEntry方法会调用first的entry方法.由于每个AbstractLinkedProcessorSlot的entry方法中都会调用fireEntry]方法,而每个fireEntry又都会调用next.entry方法,所以整个slotChain都会执行一遍.

posted on 2022-06-15 03:17  monkeydai  阅读(768)  评论(0编辑  收藏  举报

导航