Sentinel核心源码分析(上)

news2025/4/9 22:42:09

文章目录

  • 前言
  • 一、客户端与Spring Boot整合
  • 二、SphU.entry
    • 2.1、构建责任链
    • 2.2、调用责任链
      • 2.2.1、NodeSelectorSlot
      • 2.2.2、ClusterBuilderSlot
      • 2.2.3、LogSlot
      • 2.2.4、StatisticSlot
      • 2.2.5、AuthoritySlot
      • 2.2.6、SystemSlot
      • 2.2.7、FlowSlot
        • 2.2.7.1、selectNodeByRequesterAndStrategy
        • 2.2.7.2、canPass
      • 2.2.8、DegradeSlot
  • 总结


前言

  Sentinel作为Spring cloud alibaba中流控的组件,在微服务架构中也有广泛的应用。其核心源码主要体现在客户端。客户端在启动时,和Nacos类似,也会将自己的信息注册到服务端。而服务端的页面上配置各种规则时,实际上也是将信息发送到了客户端。
在这里插入图片描述
  我们最常使用的@SentinelResource注解:
在这里插入图片描述
  底层也是基于AOP + 责任链模式实现的。**Sentinel的难点不在于处理流程,而在于限流的算法。**本篇仅介绍Sentinel责任链的核心流程。


一、客户端与Spring Boot整合

  在Spring Boot项目中,如果需要引入Sentinel,通常需要在pom文件中加入:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

  该组件也是利用了Spring Boot的自动配置:
在这里插入图片描述
  其中的SentinelAutoConfiguration是核心:
在这里插入图片描述
  在SentinelAutoConfiguration中,会注册SentinelResourceAspect Bean:
在这里插入图片描述
  SentinelResourceAspect实际上是一个切面,匹配了所有加入了@SentinelResource注解的方法:
在这里插入图片描述
  invokeResourceWithSentinel是一个环绕通知。。在执行目标方法之前,首先会得到目标方法对象,以及处理注解中的一些信息,然后调用SphU.entry方法。该方法是Sentinel流程的核心。
在这里插入图片描述
  点击进去,会调用到entry方法:
在这里插入图片描述
  Env在实例化之前,会触发static中的逻辑:
在这里插入图片描述
  在doInit方法中,又会通过SPI机制,加载InitFunc中的类:
在这里插入图片描述
在这里插入图片描述
  其中的HeartbeatSenderInitFunc是定期向服务端发送心跳的:
在这里插入图片描述
在这里插入图片描述
  CommandCenterInitFunc,是将客户端各种接收规则的接口信息,暴露给服务端:
在这里插入图片描述
  上面的逻辑,包括后续构建,执行责任链,是在切面中,并非是在应用启动时执行的,而是在执行加入了@SentinelResource注解的方法时才会去执行!

二、SphU.entry

  SphU.entry方法内部主要做了两件事:

  • 构建责任链。
  • 按照顺序依次调用责任链。

在这里插入图片描述

2.1、构建责任链

  在进入lookProcessChain方法后,首先通过双检锁模式,判断当前加入了@SentinelResource注解的方法,是否已经为其构建过责任链,如果没有,才会执行newSlotChain方法。也就是说,是每一个加入了注解的方法,都有一个对应的责任链,并且只在应用启动后该方法第一次被调用时初始化。
在这里插入图片描述
  最终调用的是DefaultSlotChainBuilderbuild方法:
在这里插入图片描述
  在该方法中,主要做了两件事:
在这里插入图片描述

  通过SPI机制,加载ProcessorSlots文件中的类(责任链中的具体组成类)。

在这里插入图片描述
  真正地去构建责任链:在执行ProcessorSlotChain chain = new DefaultProcessorSlotChain();这一段代码时,实际上是构造了:
在这里插入图片描述
  构造出的是下图的数据结构,end是指向first的引用:
在这里插入图片描述
  在构造完成后,就会利用chain.addLast((AbstractLinkedProcessorSlot<?>) slot);方法,向上图的数据结构中插入具体的责任链类了:
在这里插入图片描述
  首先将end的next指针指向NodeSelectorSlot,因为end是指向指向first的引用,实际上first的next指针也指向了NodeSelectorSlot:
在这里插入图片描述
  然后将end指向NodeSelectorSlot:
在这里插入图片描述
  以此类推,最终构建出的责任链是:
在这里插入图片描述
图片来源:图灵学院

2.2、调用责任链

  这里我们重点关注FlowSlot和DegradeSlot,它们是sentinel核心功能-限流熔断降级的体现。

2.2.1、NodeSelectorSlot

  首先调用的是NodeSelectorSlot,它的作用是构建资源调用的统计节点,用于记录调用链路信息,并且将资源关联到相应的 DefaultNode。
在这里插入图片描述
  fireEntry就是在满足条件的情况下,继续调用后续的责任链。

2.2.2、ClusterBuilderSlot

  ClusterBuilderSlotNodeSelectorSlot是类似的,它的作用是构建统计节点的聚合关系。但是NodeSelectorSlot 是按调用链统计,ClusterBuilderSlot 是按资源维度统计。
在这里插入图片描述

2.2.3、LogSlot

  LogSlot的作用,是在后续的责任链调用过程中出现异常时,进行日志的记录,体现在它的try…catch中:
在这里插入图片描述

2.2.4、StatisticSlot

  StatisticSlot是先将请求放行到后续的责任链,在后续的责任链调用完成后,再去进行统计资源的调用情况的操作。例如记录 QPS(每秒请求数)、RT(响应时间)、线程数、异常数等。
在这里插入图片描述
  包括抛出了各种异常之后的记录,这些记录都是执行降级、限流等控制的基础数据来源。
在这里插入图片描述

2.2.5、AuthoritySlot

  AuthoritySlot是进行授权规则的检查,例如黑白名单:
在这里插入图片描述


  简单回顾一下黑白名单的使用,首先需要在sentinel控制台的授权规则选项卡进行配置:
在这里插入图片描述
  这里的资源名,是http请求的路径,而流控应用,可以是特定的ip,也可以是请求路径:

@Component
public class IPLimiter implements RequestOriginParser {

	/**
	*	获取当前服务实例的ip
	*/
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        return httpServletRequest.getRemoteAddr();
    }
}

  在checkBlackWhiteAuthority方法中,首先会获取所有设置的规则,然后根据当前的资源名,获取该资源对应的所有规则
在这里插入图片描述
  然后进行检查:
在这里插入图片描述
  这里的黑白名单体现在RuleConstant这个常量类中:
在这里插入图片描述
  判断逻辑有点绕:

  • 如果规则中的IP或路径,和请求中的匹配,contain会为true,反之为false。
  • 在黑名单的判定中,如果contain为true,则返回false,代表请求不通过。因为黑名单就是要对能和规则匹配上的请求进行拦截。
  • 在白名单的判断中,如果contain为false,则返回false,代表请求不通过。因为contain为false,代表请求和规则匹配不上,也就是不在白名单中。

在这里插入图片描述

2.2.6、SystemSlot

  SystemSlot是对系统规则进行控制,包括系统整体的 QPS,平均响应时间(RT),当前系统的并发线程数等。
在这里插入图片描述
在这里插入图片描述

2.2.7、FlowSlot

  FlowSlot是 Sentinel 的核心功能之一,用于流量控制(限流)规则判断。
在这里插入图片描述
  同样会获取到控制台设置的所有规则,然后逐个进行匹配:
在这里插入图片描述
  最终调用到的是passLocalCheck,其中也有两个关键方法:
在这里插入图片描述

2.2.7.1、selectNodeByRequesterAndStrategy

  selectNodeByRequesterAndStrategy用于在执行限流时 选择哪个节点(Node)来做统计和判断。不同的来源(origin)和限流策略(strategy)决定了限流数据统计的维度。首先会获取到流控模式,也就是控制台设置的:
在这里插入图片描述

  • 匹配指定 origin 的限流
    • 如果是直接模式,就利用context.getOriginNode(); 调用方自己的统计节点限流。
    • 如果是其他策略,利用selectReferenceNode再次匹配:

在这里插入图片描述

  • 如果来源是default
    • 直接限流时,使用当前资源的全局统计节点
    • 非直接限流,使用关联资源的统计节点。
  • 如果来源是other
    • 直接限流时,使用当前资源的全局统计节点
    • 非直接限流,使用关联资源的统计节点。
2.2.7.2、canPass

  在拿到上一步推断出的节点后,会调用canPass方法,这里的canPass也有不同的实现:
在这里插入图片描述
  对应控制台中的:
在这里插入图片描述
  这里涉及到滑动窗口,令牌桶,漏桶算法,会在后续进行说明。 Sentinel的难点不在于流程,而是算法。

2.2.8、DegradeSlot

  DegradeSlot的作用是熔断降级控制。也是 Sentinel 的核心功能之一:在这里插入图片描述
  在tryPass方法中,会对逐条规则进行校验,如果此时的断路器处于打开状态,
在这里插入图片描述
  并且超过了熔断时间,会修改状态为半开
在这里插入图片描述

  熔断降级中有一个重要的概念,也就是断路器。在Sentinel 1.8 版本之后,断路器有三种状态,都记录在CircuitBreaker的内部State枚举类中:在这里插入图片描述
  在这里简单的说一下三种状态的转换:

  1. 正常情况下,断路器处于关闭状态,所有请求正常通过。
  2. 当请求触发了降级条件(如异常比例过高、RT过大) 后,断路器会进入打开状态,在接下来的熔断时长内(如 10 秒),所有请求都被拒绝(降级)。
  3. 当熔断时长结束后,下一个请求到达时,断路器进入半开状态:
    • 如果该请求再次触发降级条件,断路器重新回到打开状态。
    • 如果该请求通过且正常,断路器会恢复为关闭状态。

Closed → [触发降级条件] → Open → [熔断时长结束,下一请求] → Half-Open
↑ ↓
└────── [探测失败] ←──── [探测成功] ←──────────────┘

总结

  本篇介绍了Sentinel 实现控制台功能,在服务端的实现原理:通过AOP + 责任链模式实现。并且在调用目标方法时,为每一个请求都创建一份责任链,放入缓存,依次调用。
  后面几个责任链的实现,在规则校验不通过时,都会抛出异常,而真正处理的逻辑,在StatisticSlot的catch中,以及SentinelResourceAspect#invokeResourceWithSentinelentry.exit中,包括处理断路器的状态。

下一篇:Sentinel核心源码分析(下)

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

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

相关文章

Systemd安全加密备份系统与智能通知

实训背景 你是一家金融科技公司的系统架构师&#xff0c;需为敏感数据设计一套安全备份系统&#xff0c;满足以下需求&#xff1a; 加密存储&#xff1a;自动解密插入的LUKS加密USB设备&#xff0c;挂载到安全目录。备份验证&#xff1a;备份完成后校验文件完整性&#xff0c…

6.0 使用Qt+ OpenCV+Python加载图片

本例作为python图像处理的入门课程1,使用Qt+ OpenCV+Python加载图片。 主要有如下几个地方需要注意: 1. OpenCV 默认使用 BGR 格式,而 Qt 使用 RGB。显示前需要转换:cv2.cvtColor(img, cv2.COLOR_BGR2RGB),一般使用某个QLabel控件进行显示。 pic = cv2.cvtColor(pic, cv2.C…

【Mac 从 0 到 1 保姆级配置教程 11】- Mac 基础配置 Finder、触控板、常用快捷键等

文章目录 前言配置 Finder1. 把我们的家目录请出来2. 显示文件扩展名3. 展示隐藏文件4. 显示路径栏和状态栏5. 固定文件夹到工具栏 基础快捷键1. Finder 导航快捷键2. 文件操作快捷键3. 视图和显示快捷键4. 搜索和选择快捷键5. 实用技巧6. 关于文件创建 配置触控板1. 右键设置2…

C++Primer - 动态内存管理

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

DeepSeek本地部署(Ollama)

1. Ollama 安装 Ollama 官网地址&#xff1a; https://ollama.com/安装包网盘地址: https://pan.baidu.com 2. Deepseek 部署 根据自己电脑配置和应用需求选择不同模型&#xff0c;配置不足会导致运行时候卡顿。 版本安装指令模型大小硬盘&#xff08;存储&#xff09;显卡…

第二期:深入理解 Spring Web MVC [特殊字符](核心注解 + 进阶开发)

前言&#xff1a; 欢迎来到 Spring Web MVC 深入学习 的第二期&#xff01;在第一期中&#xff0c;我们介绍了 Spring Web MVC 的基础知识&#xff0c;学习了如何 搭建开发环境、配置 Spring MVC、编写第一个应用&#xff0c;并初步了解了 控制器、视图解析、请求处理流程 等核…

论伺服电机在轨道式巡检机器人中的优势及应用实践​

一、引言​ 1.1 研究背景与意义​ 在现代工业生产、电力系统、轨道交通等诸多领域&#xff0c;保障设施设备的安全稳定运行至关重要。轨道式巡检机器人作为一种高效、智能的巡检工具&#xff0c;正逐渐在这些领域崭露头角。它能够沿着预设轨道&#xff0c;对目标区域进行全方位…

(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)

源代码 如上图将7个文放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?…

react-router children路由报错

项目场景&#xff1a; 写个路由页面&#xff0c;引发的问题 问题描述 报错&#xff1a; An absolute child route path must start with the combined path of all its parent routes. 代码&#xff1a; import { createBrowserRouter } from "react-router-dom";…

Socket编程TCP

Socket编程TCP 1、V1——EchoServer单进程版2、V2——EchoServer多进程版3、V3——EchoServer多线程版4、V4——EchoServer线程池版5、V5——多线程远程命令执行6、验证TCP——Windows作为client访问Linux7、connect的断线重连 1、V1——EchoServer单进程版 在TcpServer.hpp中实…

文件映射mmap与管道文件

在用户态申请内存&#xff0c;内存内容和磁盘内容建立一一映射 读写内存等价于读写磁盘 支持随机访问 简单来说&#xff0c;把磁盘里的数据与内存的用户态建立一一映射关系&#xff0c;让读写内存等价于读写磁盘&#xff0c;支持随机访问。 管道文件&#xff1a;进程间通信机…

代码随想录回溯算法03

93.复原IP地址 本期本来是很有难度的&#xff0c;不过 大家做完 分割回文串 之后&#xff0c;本题就容易很多了 题目链接/文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;回溯算法如何分割字符串并判断是合法IP&#xff1f;| LeetCode&#xff1a;93.复原IP地址_哔哩哔…

批量改CAD图层颜色——CAD c#二次开发

一个文件夹下大量图纸&#xff08;几百甚至几千个文件&#xff09;需要改图层颜色时&#xff0c;可采用插件实现&#xff0c;效果如下&#xff1a; 转换前&#xff1a; 转换后&#xff1a; 使用方式如下&#xff1a;netload加载此dll插件&#xff0c;输入xx运行。 附部分代码如…

【内网安全】DHCP 饿死攻击和防护

正常情况&#xff1a;PC2可以正常获取到DHCP SERVER分别的IP地址查看DHCP SERCER 的ip pool地址池可以看到分配了一个地址、Total 253个 Used 1个 使用kali工具进行模拟攻击 进行DHCP DISCOVER攻击 此时查看DHCP SERVER d大量的抓包&#xff1a;大量的DHCP Discover包 此时模…

10种电阻综合对比——《器件手册--电阻》

二、电阻 前言 10种电阻对比数据表 电阻类型 原理 特点 应用 贴片电阻 贴片电阻是表面贴装元件&#xff0c;通过将电阻体直接贴在电路板上实现电路连接 体积小、重量轻&#xff0c;适合高密度电路板&#xff1b;精度高、稳定性好&#xff0c;便于自动化生产 广泛应用于…

剑指Offer(数据结构与算法面试题精讲)C++版——day6

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day6 题目一&#xff1a;不含重复字符的最长子字符串题目二&#xff1a;包含所有字符的最短字符串题目三&#xff1a;有效的回文 题目一&#xff1a;不含重复字符的最长子字符串 这里还是可以使用前面&#x…

freertos韦东山---事件组以及实验

事件组的原理是什么&#xff0c;有哪些优点&#xff0c;为啥要创造出这个概念 在实时操作系统&#xff08;如 FreeRTOS&#xff09;中&#xff0c;事件组是一种用于任务间同步和通信的机制&#xff0c;它的原理、优点及存在意义如下&#xff1a; 事件组原理 数据结构&#xf…

架构师面试(二十六):系统拆分

问题 今天我们聊电商系统实际业务场景的问题&#xff0c;考查对业务系统问题的分析能力、解决问题的能力和对系统长期发展的整体规划能力。 一电商平台在早期阶段业务发展迅速&#xff0c;DAU在 10W&#xff1b;整个电商系统按水平分层架构进行设计&#xff0c;包括【入口网关…

Java中的同步和异步

一、前言 在Java中&#xff0c;同步&#xff08;Synchronous&#xff09;和异步&#xff08;Asynchronous&#xff09;是两种不同的任务处理模式。核心区别在任务执行的顺序控制和线程阻塞行为。 二、同步&#xff08;Synchronous&#xff09; 定义&#xff1a;任务按顺序执行…

在 Ubuntu24.04 LTS 上 Docker Compose 部署基于 Dify 重构二开的开源项目 Dify-Plus

一、安装环境信息说明 硬件资源&#xff08;GB 和 GiB 的主要区别在于它们的换算基数不同&#xff0c;GB 使用十进制&#xff0c;GiB 使用二进制&#xff0c;导致相同数值下 GiB 表示的容量略大于 GB&#xff1b;换算关系&#xff1a;1 GiB ≈ 1.07374 GB &#xff1b;1 GB ≈ …