【RuoYi-Cloud-Plus】学习笔记 07 - Sentinel(二)Node ProcessorSlotChain 总览与知识整理

news2024/11/26 16:48:51

文章目录

    • 前言
    • 参考目录
    • 版本说明
    • 学习笔记
      • 1、Sentinel 架构图
      • 2、Node
      • 2.1、入口节点 `EntranceNode`
      • 2.2、链路节点 `DefaultNode`
      • 2.3、簇点 `ClusterNode`
      • 2.4、统计节点 `StatisticNode`
      • 3、`Slot Chain`
      • 3.1、`DefaultSlotChainBuilder`
      • 3.1.1、Slot 排序的实现
      • 3.1.2、SPI 文件读取
      • 3.2、`NodeSelectorSlot`(order = -10000)
      • 3.3、`ClusterBuilderSlot`(order = -9000)
      • 3.4、`LogSlot`(order = -8000)
      • 3.5、`StatisticSlot`(order = -7000)
      • 3.6、`AuthoritySlot`(order = -6000)
      • 3.7、`SystemSlot`(order = -5000)
      • 3.8、`GatewayFlowSlot`(order = -4000)
      • 3.9、`ParamFlowSlot`(order = -3000)
      • 3.10、`FlowSlot`(order = -2000)
      • 3.11、`DegradeSlot`(order = -1000)

前言

上一篇文章中,主要集中的点在于 StatisticSlot,一开始只是简单介绍了一下 Sentinel 架构,这篇文章暂时把视线拉回来一点,整理一下关于 Node 以及 slot chain 的相关知识,后续文章再对 slot 展开详细分析。

参考目录

  • Sentinel 官方文档
  • Sentinel工作主流程
    依托于该文档进行本文 Slot Chain 部分的展开。
  • Sentinel 核心类解析
    依托于该文档进行本文 Node 部分的展开。
  • 《实战Alibaba Sentinel:深度解析微服务高并发流量治理》
    结合该书对一些知识点的梳理。

版本说明

  • SentinelV1.8.6

学习笔记

1、Sentinel 架构图

总体架构图(搬运自官方文档):
在这里插入图片描述

还是这张图,先来简单梳理一下各种类型的 Node,然后再来分析下面的 Slot Chain

2、Node

Node 继承关系图如下:

在这里插入图片描述

这一部分在文档中分成了三个部分来对各种节点进行描述,分别是简介、构建时机以及维度(数目),下面在文档的基础上结合源码来整理说明一下。

2.1、入口节点 EntranceNode

  • 介绍:

入口节点,特殊的链路节点,对应某个 Context 入口的所有调用数据。Constants.ROOT 节点也是入口节点。

在这里插入图片描述

  • 构建的时机:

在 ContextUtil.enter(xxx) 的时候就创建了,然后塞到 Context 里面。

在这里插入图片描述

  • 维度(数目):

维度是 context,存在 ContextUtil 类的 contextNameNodeMap 里面。

在这里插入图片描述

2.2、链路节点 DefaultNode

  • 介绍:

用于统计调用链路上某个资源的数据,维持树状结构。

在这里插入图片描述

  • 构建的时机:

NodeSelectorSlot:根据 context 创建 DefaultNode,然后 set curNode to context。

在这里插入图片描述

该方法 NodeSelectorSlot#entry 会在下面介绍 Slot Chain 时再作说明。

  • 维度(数目):

维度是 resource * context,存在每个 NodeSelectorSlot 的 map 里面。

在这里插入图片描述

2.3、簇点 ClusterNode

  • 介绍:

用于统计每个资源全局的数据(不区分调用链路),以及存放该资源的按来源区分的调用数据(类型为 StatisticNode)。特别地,Constants.ENTRY_NODE 节点用于统计全局的入口资源数据。

在这里插入图片描述

  • 构建的时机:

ClusterBuilderSlot:首先根据 resourceName 创建 ClusterNode,并且 set clusterNode to defaultNode。

在这里插入图片描述
同上,该方法 ClusterBuilderSlot#entry 会在下面介绍 Slot Chain 时再作说明。

  • 维度(数目):

维度是 resource。

在这里插入图片描述

2.4、统计节点 StatisticNode

上篇文章的主角,再来回顾一下。

  • 介绍:

最为基础的统计节点,包含秒级和分钟级两个滑动窗口结构。

在这里插入图片描述

  • 构建的时机:

ClusterBuilderSlot:首先根据 resourceName 创建 ClusterNode,并且 set clusterNode to defaultNode;然后再根据 origin 创建来源节点(类型为 StatisticNode),并且 set originNode to curEntry。

ClusterBuilderSlot#entry
在这里插入图片描述

ClusterNode#getOrCreateOriginNode
在这里插入图片描述

  • 维度(数目):

来源节点(类型为 StatisticNode)的维度是 resource * origin,存在每个 ClusterNode 的 originCountMap 里面。

在这里插入图片描述

3、Slot Chain

注:由于篇幅所限,处理器链中比较重要的 slot (例如限流、熔断等)会在后面的文章单独讲,在文本会简单带过一下。

还是先回到 Github 文档中开头的那句话:

Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起。slot chain 其实可以分为两部分:统计数据构建部分(statistic)和判断部分(rule checking)。

可以知道,Slot 是按照顺序串联起来的,所以我们也是按照加载顺序来进行说明。

在看《实战Alibaba Sentinel:深度解析微服务高并发流量治理》的时候,也有看到关于这一部分的说明,来简单摘抄如下:

Sentinel 使用责任链模式将注册的所有 ProcessorSlot 按照一定的顺序串成一个单向链表。

ProcessorSlotChain 用于将 ProcessorSlot 串成一个单向链表,并且ProcessorSlotChain 由 SlotChainBuilder 构造。DefaultSlotChainBuilder 是默认使用的 SlotChainBuilder。

既然如此,我们就从 DefaultSlotChainBuilder 开始。

3.1、DefaultSlotChainBuilder

DefaultSlotChainBuilder#build
在这里插入图片描述

该方法的主要逻辑:

  1. 创建一个 ProcessorSlotChain 对象。
  2. 通过 SPI 机制获取所有的 ProcessorSlot 实现类,并将它们按照 SPI 机制的注解(@Spi)中的 order 属性进行排序,这里的 SpiLoader 是一个工具类用于加载 SPI 实现类。
  3. 在排序后的 ProcessorSlot 列表中,只有继承自抽象的ProcessorSlot 链节点 AbstractLinkedProcessorSlotProcessorSlot 的实例才可以添加到 ProcessorSlotChain 中,否则会打印警告并忽略该 ProcessorSlot
  4. 将所有可添加的 ProcessorSlot 添加到 ProcessorSlotChain 中并返回。

这个方法的重点在于通过 SPI 机制获取所有的 ProcessorSlot 实现类。

SpiLoader#loadInstanceListSorted
在这里插入图片描述

SpiLoader#load
在这里插入图片描述

这段代码是 SPI 机制的实现代码,用于加载实现某个特定接口的 SPI 实现。

方法的主要逻辑:

  1. 判断是否已加载过该 SPI 实现,若已加载则直接返回。
  2. 根据 SPI 接口名称读取相应的 SPI 文件。
  3. 通过相应的 ClassLoader 获取这个文件的 URL,并遍历每一个 URL 来读取文件内容,解析其中的每一行字符串,提取类名称等信息加入到相应的列表中。如果文件中出现了重名的别名,则会抛出异常。
  4. 将解析出来的类进行一系列操作,比如判断它是否是该 SPI 接口的实现,或者是否是默认实现类等,并将这些类的别名、注解信息等放入相应的 Map 中。
  5. 将这些类集合进行排序并返回。

得到的 slot(未排序):
在这里插入图片描述

3.1.1、Slot 排序的实现

通过注解的 @Spi 中的 order 属性进行排序。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

排序比较:

在这里插入图片描述

3.1.2、SPI 文件读取

如何能够通过 SPI 机制获取所有的 ProcessorSlot 实现类?

答案是在资源文件夹中创建和接口名称一致的资源文件。

在这里插入图片描述

在这里插入图片描述

sentinel-core-1.8.6.jar 这里只有 8 个 slot,但是上面截图显示,加载完成的时候有 10 个 slot。这里就不得不说明一下,所有引入的 jar 包都会被扫描,只要名称相同的文件都会被扫描,所以另外两个 slot 分别在 sentinel-parameter-flow-control-1.8.6.jar 以及 sentinel-api-gateway-adapter-common-1.8.6.jar

在这里插入图片描述

在这里插入图片描述

3.2、NodeSelectorSlot(order = -10000)

这是最先加载的 slot

这个 slot 主要负责收集资源的路径,并将这些资源的调用路径以树状结构存储起来,用于根据调用路径进行流量控制。

NodeSelectorSlot#entry
在这里插入图片描述

主要逻辑:

  1. 根据不同的上下文 context 和资源封装类 ResourceWrapper 创建相应的执行节点 DefaultNode,并将其添加到一个 map 中进行缓存。
  2. 如果 map 中已有该上下文 context 对应的执行节点,则直接获取该节点;否则需要创建一个新节点添加到 map 中,并将其加入调用方上下文的调用栈(即为 DefaultNode)的子节点中,以构建所有节点的调用树。
  3. 将执行节点和相关参数传递到下一个ProcessorSlot 中进行处理。

方法的注释值得一读:

It’s interesting that we use context name rather resource name as the map key.

在这里插入图片描述

红色框中还提出了一个思考问题:

最快获取到同一个 resource 的所有统计值的方法是什么?

答案是所有具有相同 resource 名称的 DefaultNode 共享同一个 ClusterNode

3.3、ClusterBuilderSlot(order = -9000)

此插槽用于构建资源的 ClusterNode 以及调用来源节点。ClusterNode 保持某个资源运行统计信息(响应时间、QPS、block 数目、线程数、异常数等)以及调用来源统计信息列表。

在这里插入图片描述

上面关于 ClusterNode 节点的说明也有提及该方法。

这个方法的作用是创建一个新的 ClusterNode 实例,并使用node.setClusterNode(clusterNode) 将其分配给给定的 Node 对象。如果 context 参数具有非空的来源值,则它还会设置一个来源节点。

3.4、LogSlot(order = -8000)

在这里插入图片描述

这一个功能比较简单,继续往下。

3.5、StatisticSlot(order = -7000)

StatisticSlot 是 Sentinel 的核心功能插槽之一,用于统计实时的调用数据。

这一个在上篇文章 #3.3.1 中详细分析过了,在此也不再赘述。

3.6、AuthoritySlot(order = -6000)

根据配置的黑白名单和调用来源信息,来做黑白名单控制。

在这里插入图片描述

3.7、SystemSlot(order = -5000)

这个 slot 会根据对于当前系统的整体情况,对入口资源的调用进行动态调配。其原理是让入口的流量和当前系统的预计容量达到一个动态平衡。

注意系统规则只对入口流量起作用(调用类型为 EntryType.IN),对出口流量无效。可通过 SphU.entry(res, entryType) 指定调用类型,如果不指定,默认是EntryType.OUT。

在这里插入图片描述

SystemRuleManager#checkSystem
在这里插入图片描述
在这里插入图片描述

方法的主要逻辑:

  1. 如果 resourceWrapper 参数为 null,方法将直接返回。
  2. 如果检查开关 checkSystemStatus 为关闭状态,则方法也直接返回。
  3. 该方法只检查入站流量。如果资源类型不是入站类型,则方法直接返回。
  4. 计算当前总的 QPS,如果当前 QPS 加上 count 超过了最大 QPS,那么就抛出一个 SystemBlockException 异常,异常信息中包含了资源名称和限制类型 ("qps")
  5. 检查当前线程数是否超过了最大线程数,如果是,则抛出一个 SystemBlockException 异常,异常信息中也包含了资源名称和限制类型 ("thread")
  6. 计算当前的平均响应时间,如果平均响应时间超过了最大响应时间,那么就抛出一个 SystemBlockException 异常,异常信息中同样包含了资源名称和限制类型("rt")
  7. 检查系统负载是否超过了上限。如果最高系统负载已经设置,且当前系统平均负载超过了最高系统负载,那么就调用 checkBbr 方法检查是否可以通过 BBR 算法来限制流量。如果不能通过 BBR 算法来限制流量,那么就抛出一个 SystemBlockException 异常,异常信息中同样包含了资源名称和限制类型 ("load")
  8. 检查当前 CPU 使用率是否超过了最高 CPU 使用率。如果超过了最高 CPU 使用率,那么就抛出一个 SystemBlockException 异常,异常信息中同样包含了资源名称和限制类型 ("cpu")

关于 BBR 算法:

在这里插入图片描述

SystemRuleManager#checkBbr
在这里插入图片描述

入参 currentThread 当前线程数。

判断 currentThread 是否大于 1,如果大于 1,则继续判断是否大于 Constants.ENTRY_NODE.maxSuccessQps() * Constants.ENTRY_NODE.minRt() / 1000

  • 如果大于,则返回 false,表示当前线程超过了 BBR 算法的限制,应该停止继续运行。
  • 如果小于,则返回 true,表示当前线程符合 BBR 算法的限制,可以继续运行。

3.8、GatewayFlowSlot(order = -4000)

在这里插入图片描述

方法的主要逻辑:

  1. 如果 argsnull,则直接返回。
  2. 获取 GatewayRuleManager 对象,并调用 getConvertedParamRules 方法获取转化后的参数规则列表。
  3. 如果规则列表为 null 或为空,则直接返回。
  4. 遍历规则列表中的每个规则,对于每个规则:
    • 初始化参数度量器。
    • 如果 passCheck 不满足条件,则抛出参数流量限制异常 ParamFlowException
  5. 返回成功。

3.9、ParamFlowSlot(order = -3000)

在这里插入图片描述

ParamFlowSlot#checkFlow
在这里插入图片描述

热点参数限流和网关限流类似,也是通过一系列规则的判断来校验是否能够通过。

3.10、FlowSlot(order = -2000)

这个 slot 主要根据预设的资源的统计信息,按照固定的次序,依次生效。如果一个资源对应两条或者多条流控规则,则会根据如下次序依次检验,直到全部通过或者有一个规则生效为止:
指定应用生效的规则,即针对调用方限流的;
调用方为 other 的规则;
调用方为 default 的规则。

在这里插入图片描述

3.11、DegradeSlot(order = -1000)

这个 slot 主要针对资源的平均响应时间(RT)以及异常比率,来决定资源是否在接下来的时间被自动熔断掉。

在这里插入图片描述

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/643518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java并发工具之ThreadLocal

一、ThreadLocal 简介 1. ThreadLocal 是什么? ThreadLocal 字面意思是本地线程,其实更准确来说是线程局部变量,线程类 Thread 有个变量叫做 threadLocals,其类型就是ThreadLocal.ThreadLocalMap 类型,他其实不是一个…

回忆童年游戏,完美利用Python制作飞机大战(爷青回~)

名字:阿玥的小东东 学习:python、C/C 博客链接:阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 pygame包的安装 添加python环境变量 创建飞机大战窗口 飞机照片 将变量及函数抽取出来 添加多…

LeetCode:31. 下一个排列

31. 下一个排列 1)题目2)思路3)代码4)结果 1)题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1…

Nacos负载均衡策略

文章目录 按权重分配流量负载均衡自定义负载均衡策略 按权重分配流量负载均衡 SpringCloud新版本(2021.x.x)中负载均衡器用LoadBalancer替代了Ribbon,默认只提供了2种负载均衡策略:RandomLoadBalancer 和 RoundRobinLoadBalancer。…

[冷冻电镜]IMOD使用指南

参考教程: Etomo Tuturial for IMOD version 4.11 1. Initial Setup 本教程提供了一个小双轴示例数据集和Etomo的分布指南,更详细的内容参考Tomography Guide。该版本使用1k*1k的图像而不是压缩版本。imodhelp命令可以打开帮助界面,查看各种…

java并发之CAS(Compare and swap)

1. 简介 CAS的底层调用native方法,最终是利用CPU的一个特殊指令,该指令由CPU保证了原子性,而且包含多个操作,比如先比较再更新。 原理: (1)需要读写的内存值(V)、原值…

【Kafka】Docker安装kafkajava kafka api

内容目录 一、安装zookeeper1 拉取镜像2 创建network3 启动容器 二、安装kafka1 拉取kafka镜像2 启动kafka容器3 创建topic4 创建生产者5 创建消费者 三、kafka的java api1 producer2 消费者 docker依赖于zookeeper,首先安装zookeeper 一、安装zookeeper 1 拉取镜像…

[PyTorch][chapter 40][数据增强]

前言: 深度学习对数据量要求非常大, 我们通常会遇到图像的数据集比较小,影响Train效果。 这个时候可以通过transformer 方法,增加图像的多样性,达到数据 增强的效果。 transformer 不会单独使用,通常和其它torch 其他类一起使用 transformer 常用方法…

可视管理 数字孪生智慧隧道一体化管控平台

前言 交通是国家发展的关键,四通八达的交通路线,对国家经济、社会等方面的发展起着至关重要的作用。 建设背景 随着社会经济的持续发展与城市化进程的平稳推进,我国公路工程规模逐步扩大,公路工程建设直接影响着城市未来发展与…

Vue 报错 error:0308010C:digital envelope routines::unsupported

症状 Vue 报错error:0308010C:digital envelope routines::unsupported 原因 出现这个错误是因为 node.js V17版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制,可能会对生态系统造成一些影响. 解决方法 方法1 打开终端&#x…

React 应用 Effect Hook 函数式中操作生命周期

React Hook入门小案例 在函数式组件中使用state响应式数据给大家演示了最简单的 Hook操作 那么 我们继续 首先 Hook官方介绍 他没有破坏性是完全可选的 百分比兼容 也就说 我们一起的 类 class的方式也完全可以用 只要 react 16,8以上就可以使用 Hook本身不会影响你的react的理…

ESXi 7.0 U3m Hitachi (日立) 定制版 OEM Custom Installer CD

VMware ESXi 7.0 Update 3m - 领先的裸机 Hypervisor (All OEM Customized Installer CDs) ESXi 7.0 U3m Standard (标准版) ESXi 7.0 U3m Dell (戴尔) 定制版 OEM Custom Installer CD ESXi 7.0 U3m HPE (慧与) 定制版 OEM Custom Installer CD ESXi 7.0 U3m Lenovo (联想) 定…

4.单表查询

SQL句子中语法格式提示: 1.中括号([])中的内容为可选项; 2.[,...]表示,前面的内容可重复; 3.大括号({})和竖线(|)表示选择项,在选择…

chatgpt赋能python:Python怎么导入第三方库

Python怎么导入第三方库 如果你是Python开发者,你一定会使用各种第三方库来加速你的开发过程。这些库可能是Python标准库之外的代码,或由其他人编写的自定义代码。使用这些库可以让你的开发更高效、更易于管理,并且可以避免重复造轮子。 但…

RabbitMQ虚拟主机无法启动的原因和解决方案

RabbitMQ虚拟主机无法启动的原因和解决方案 摘要: RabbitMQ是一个广泛使用的开源消息代理系统,但在使用过程中可能会遇到虚拟主机无法启动的问题。本文将探讨可能导致该问题的原因,并提供相应的解决方案,以帮助读者解决RabbitMQ虚…

Learning C++ No.31 【线程库实战】

引言: 北京时间:2023/6/11/14:40,实训课中,实训场地有空调,除了凳子坐着不舒服之外,其它条件都挺好,主要是我带上了我自己的小键盘,并且教室可以充电,哈哈哈&#xff0c…

在做自动化测试之前你需要知道的

B站视频教程:Python自动化测试:7天练完这60个实战项目,年薪过35w。 什么是自动化测试? 做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多。一直想动笔写一篇文章分享自动化测试实践…

信息系统管理工程师-学习笔记1-信息化知识

考点1 信息与信息系统 信息的概念 信息的定义: 是有别与物质与能量的第三种东西,是对事物运动状态或存在方式的不确定行的描述 信息是按特定方式组织在一起的客体属性的集合,具有超出这些客体属性本身之外的价值两层次 1.本体论层次 : 纯客观的层次,只与客体本身的因素有关,与主…

python cv2的一些操作,如膨胀,画线,滤波等

目录 0. cv2简介1. 打开摄像头2. 画图,画线3. 滤波4. 获取角点5. 梯度边缘6. 图形匹配7. 形态学变化-膨胀腐蚀8. 二值化阈值10. 总结 0. cv2简介 在这里先简单介绍一下cv2吧。 cv2 是 OpenCV Python 库的主要模块,提供了许多图像处理和计算机视觉方面的函数和工具。…

vue2组件通信

父传子 传递静态或动态 Prop <!-- 传入静态值 --> <blog-post title"hai hai hai"></blog-post><!-- 传入变量值 --> <blog-post :title"info.title"></blog-post>传入一个对象的所有 property 数据 post: {id: 1…