Sentinel源码解析-请求入口


一、Sentinel架构

在这里插入图片描述
从上述架构图中可以看出Sentinlel的核心就是一个处理链一次请求过来会经过处理链上的多个slot处理来进行熔断降级流控等核心功能对应每个slot的具体实现我们在后续会逐一进行讲解。

二、@SentinelResouce处理流程

1. SentinelResourceAspect-入口

在上篇源码环境搭建的时候我们通过在方法上标注@SentinelResouce注解来表示这个是sentinel的一个资源然后就在sentinel- dashboard上面配置对应的流控规则来实现限流逻辑。注解的处理逻辑是在SentinelResourceAspect这个切面中进行处理

在这里插入图片描述

1.1 getResourceName(获取资源名)

这里首先判断注解中有没有指定资源名如果指定了资源名就用注解指定的如果没有指定资源名则通过解析方法通过通过方法所在类+方法名+方法参数类名拼接出来一个资源名

在这里插入图片描述

1.2 SphU#entry(核心增强逻辑)

这里会真正调用EnvsphentryWithType来执行真正处理逻辑。

在这里插入图片描述

1.2.1. Env

这里我们发现

  1. sph的一个具体实现是CtSph
  2. Env的静态代码块中会调用InitExecutor#doInit方法

在这里插入图片描述

1.2.2. InitExecutor#doInit

initExecutor#doinit方法中会去加载初始化组件会通过spi加载对应的初始化组件找到InitFunc的实现类并排序进行初始化操作。

在这里插入图片描述

1.2.3.InitFunc实现类

这里看好像是环境的初始化操作初始化需要的对应组件不是主线逻辑我们在Env中已经知道sph的具体实现是CtSph我们继续追踪下CtSph#entryWithType方法。

在这里插入图片描述

1.2.4. entryWithType

  1. 这里把nameentryType和ResourceType包装成一个ResourceWrapper
  2. 继续调用entryWithPriority方法

在这里插入图片描述

1.2.5 entryWithPriority

  1. 首先会给当前线程绑定一个context
  2. 查找对应的slotChain也就是对应对这个资源的一个处理链
  3. 调用chain#entry方法对资源进行过处理链的操作

在这里插入图片描述

1.2.5.1 ContextUtil#getContext

这里会调用contextHolder#get方法contextHolder是一个ThreadLocal如果从ThreadLocal中没有获取到当前线程的context,则后续会调用InternalContextUtil#internalEnter方法初始化一个context放进来

在这里插入图片描述

1.2.5.2 ContextUtil#initDefaultContext

这里我们看到ContextUtil的静态代码块中会调用initDefaultContext方法来初始化默认的上下问首先通过 Constants.ROOT创建一个root节点然将新创建的Node节点加入到root的字节点中并存入contextNameNodeMap

在这里插入图片描述

1.2.5.3 Tree、Node、Context的关系

首先是这个Tree这个Tree是由NodeSelectorSlot这个插槽来创建的每创建一个树都有一个Root节点这个Root节点就代表的是一个应用一个应用只会创建一个Root节点。就比如说一个一个dubbo项目中会有provider和consumer这一个consumer就是一个应用。

在这里插入图片描述

一个应用中可以定义很多资源可以是代码块、方法等等

在这里插入图片描述

当属于同一个应用下的请求过来后会首先判断是否有Root没有的话就会新建一个Root节点。
再往下就会出现EntranceNodeDefaultNodeCLusterNode三种node那这三种节点又是什么关系呢我们首先看一下这三个节点类的关系图

其中StatsticNode是用作数据统计的那根据继承关系其三个子类Node也是进行数据统计那他们分别的作用又是什么呢
在讲这三个Node前大家要明白Sentinel的一个核心概念Context
Context是对资源操作的上下文每个资源操作必须属于一个Context。它会保存一次资源访问链路元数据和该资源所对应的实时信息链路的各个节点都能通过获取链路绑定的context来获取一些信息进行相应的处理。如果代码中没有指定Context则会创建一个namesentinel_default_context的默认Context。一个Context生命周期中可以包含多个资源操作。Context生命周期中的最后一个资源在exit()时会清理该Conetxt这也就意味着这个Context生命周期结束了。

在这里插入图片描述

Node用于完成数据统计的接口
StatisticNode统计节点是Node接口的实现类用于完成数据统计
EntranceNode入口节点一个Context会有一个入口节点用于统计当前Context的总体流量数据
DefaultNode默认节点用于统计一个资源在当前Context中的流量数据
ClusterNode集群节点用于统计一个资源在所有Context中的总体流量数据

在这里插入图片描述

1.2.5.4 InternalContextUtil#internalEnter

如果发现当前请求线程如果没有绑定context则给当前线程绑定一个名为sentinel_default_contextcontext

在这里插入图片描述

1.2.5.5 SlotChainProvider#newSlotChain
  1. 首先根据当前资源从缓存中获取处理链
  2. 没有获取到则调用SlotChainProvider#newSlotChain构造处理链

在这里插入图片描述

1.2.5.6 CtSph#lookProcessChain(构造处理链)
  1. 这里首先通过SPI方式创建builder如果你没有指定则会创建一个DefaultSlotChainBuilder

在这里插入图片描述

1.2.5.6 DefaultSlotChainBuilder#build
  1. 这里会创建一个ProcessorSlotChain
  2. 通过SPI机制获取对应的处理链中的slot,这里会去sentinel-core/src/main/resources/META-INF/services找对应的Slot然后进行初始化
  3. slot添加到处理链中

在这里插入图片描述
在这里插入图片描述

1.2.5.7 DefaultProcessorSlotChain#entry

这里会调用到处理链中的具体的slot每个slot的具体实现我们后续文章继续分析。

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6