sentinel源码分析-03构建执行链

MaxDEA如何计算超效率DEA MaxDEA如何计算超效率DEA第一步,导入数据,设置输出和输出,点击OK;第二步,运行模型; 本文计算的是超效率DEA-BCC。 第一步,导入数据,设置输出和输出,点击OK; 第二步,运行模型; 在distance选项框中选择Radial:CCR(1978);BCC(1984)。 在Orientation中选择Non-oriented。其中,Input-oriented是投入最小;Outp... 阅读详情

构建执行链

上文中我们分析了核心逻辑入口是SphU.entry(target, EntryType.IN),我们只分析了一些初始化逻辑下面,我们分析一下核心限流处理逻辑

public class Env {

    public static final Sph sph = new CtSph();

    static {
        // If init fails, the process will exit.
        //初始化
        InitExecutor.doInit();
    }

}

CtSph类的

public Entry entry(String name, EntryType type, int count, Object... args) throws BlockException {
		//封装成resource
        StringResourceWrapper resource = new StringResourceWrapper(name, type);
        return entry(resource, count, args);
    }

经过执行逻辑跟踪最终会走到entryWithPriority方法

private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args)
        throws BlockException {
        //之前已经创建了上下文
        Context context = ContextUtil.getContext();
        //超出了创建context数量限制
        if (context instanceof NullContext) {
            // The {@link NullContext} indicates that the amount of context has exceeded the threshold,
            // so here init the entry only. No rule checking will be done.
            return new CtEntry(resourceWrapper, null, context);
        }
        //之前还没创建context
        if (context == null) {
            // Using default context.
            context = MyContextUtil.myEnter(Constants.CONTEXT_DEFAULT_NAME, "", resourceWrapper.getType());
        }

        // Global switch is close, no rule checking will do.
        // 全局开关已关闭,不会进行任何规则检查。
        if (!Constants.ON) {
            return new CtEntry(resourceWrapper, null, context);
        }
        //核心方法-构建拦截链路
        ProcessorSlot<Object> chain = lookProcessChain(resourceWrapper);

        /*
         * Means amount of resources (slot chain) exceeds {@link Constants.MAX_SLOT_CHAIN_SIZE},
         * so no rule checking will be done.
         */
        //资源的拦截链数量超过最大值,则不执行任何规则检查
        if (chain == null) {
            return new CtEntry(resourceWrapper, null, context);
        }

        Entry e = new CtEntry(resourceWrapper, chain, context);
        try {
            //开启链路调用
            chain.entry(context, resourceWrapper, null, count, prioritized, args);
        } catch (BlockException e1) {
            e.exit(count, args);
            throw e1;
        } catch (Throwable e1) {
            // This should not happen, unless there are errors existing in Sentinel internal.
            RecordLog.info("Sentinel unexpected exception", e1);
        }
        return e;
    }

这里主要完成以下几个事情

  • 创建运行上下文
private static ThreadLocal<Context> contextHolder = new ThreadLocal<>();

public static Context getContext() {
   return contextHolder.get();
}

首先查看之前线程有没有创建了context,如果已经有了就直接获取,如果没有则创建默认的context

protected static Context trueEnter(String name, String origin) {
        //每个线程一个Context
        Context context = contextHolder.get();
        if (context == null) {
            Map<String, DefaultNode> localCacheNameMap = contextNameNodeMap;
            DefaultNode node = localCacheNameMap.get(name);
            if (node == null) {
                if (localCacheNameMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
                    setNullContext();
                    return NULL_CONTEXT;
                } else {
                    try {
                        LOCK.lock();
                        node = contextNameNodeMap.get(name);
                        if (node == null) {
                            if (contextNameNodeMap.size() > Constants.MAX_CONTEXT_NAME_SIZE) {
                                setNullContext();
                                return NULL_CONTEXT;
                            } else {
                                //入口node,name:"sentinel_default_context"
                                node = new EntranceNode(new StringResourceWrapper(name, EntryType.IN), null);
                                // Add entrance node.
                                Constants.ROOT.addChild(node);
                                //为什么重新创建map进行赋值,不直接使用ConcurrentHashMap
                                Map<String, DefaultNode> newMap = new HashMap<>(contextNameNodeMap.size() + 1);
                                newMap.putAll(contextNameNodeMap);
                                newMap.put(name, node);
                                contextNameNodeMap = newMap;
                            }
                        }
                    } finally {
                        LOCK.unlock();
                    }
                }
            }
            context = new Context(node, name);
            context.setOrigin(origin);
            contextHolder.set(context);
        }

        return context;
    }

每一个上下文问都会对应一个EntranceNode,他是调用的入口节点,不同调用方式不同的EntranceNode

  • 构建核心拦截链路
ProcessorSlot<Object> lookProcessChain(ResourceWrapper resourceWrapper) {
        ProcessorSlotChain chain = chainMap.get(resourceWrapper);
        if (chain == null) {
            synchronized (LOCK) {
                chain = chainMap.get(resourceWrapper);
                if (chain == null) {
                    // Entry size limit.
                    if (chainMap.size() >= Constants.MAX_SLOT_CHAIN_SIZE) {
                        return null;
                    }
                    //构建过滤链
                    chain = SlotChainProvider.newSlotChain();
                    Map<ResourceWrapper, ProcessorSlotChain> newMap = new HashMap<ResourceWrapper, ProcessorSlotChain>(
                        chainMap.size() + 1);
                    newMap.putAll(chainMap);
                    newMap.put(resourceWrapper, chain);
                    chainMap = newMap;
                }
            }
        }
        return chain;
    }
public static ProcessorSlotChain newSlotChain() {
        if (builder != null) {
            return builder.build();
        }
        //获取请求链创建builder
        resolveSlotChainBuilder();

        if (builder == null) {
            RecordLog.warn("[SlotChainProvider] Wrong state when resolving slot chain builder, using default");
            builder = new DefaultSlotChainBuilder();
        }
        return builder.build();
    }
private static final ServiceLoader<SlotChainBuilder> LOADER = ServiceLoader.load(SlotChainBuilder.class);
private static void resolveSlotChainBuilder() {
        List<SlotChainBuilder> list = new ArrayList<SlotChainBuilder>();
        boolean hasOther = false;
        //通过SPI机制获取连接链builder
        for (SlotChainBuilder builder : LOADER) {
            if (builder.getClass() != DefaultSlotChainBuilder.class) {
                hasOther = true;
                list.add(builder);
            }
        }
        if (hasOther) {
            builder = list.get(0);
        } else {
            // No custom builder, using default.
            builder = new DefaultSlotChainBuilder();
        }

        RecordLog.info("[SlotChainProvider] Global slot chain builder resolved: "
            + builder.getClass().getCanonicalName());
    }

这里又是通过SPI机制获取所有SlotChainBuilder的实现类,查看META-INF.services下的com.alibaba.csp.sentinel.slotchain.SlotChainBuilder文件

# Default slot chain builder
com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder

通过DefaultSlotChainBuilder构建了整个核心拦截链

public class DefaultSlotChainBuilder implements SlotChainBuilder {

    @Override
    public ProcessorSlotChain build() {
        ProcessorSlotChain chain = new DefaultProcessorSlotChain();
        //收集资源的路径,将调用路径以树状结构存储起来,根据调用路径来限流降级
        chain.addLast(new NodeSelectorSlot());
        //负责调用来源的信息统计和ClusterNode某个资源的统计信息
        chain.addLast(new ClusterBuilderSlot());
        //在抛出BlockException的时候,会通过该类来输入一些日志信息
        chain.addLast(new LogSlot());
        //用于记录、统计不同维度的运行指标监控信息
        chain.addLast(new StatisticSlot());
        //全局的指标统计
        chain.addLast(new SystemSlot());
        //根据配置的黑白名单和调用来源信息,来做黑白名单控制
        chain.addLast(new AuthoritySlot());
        //限流
        chain.addLast(new FlowSlot());
        //降级
        chain.addLast(new DegradeSlot());

        return chain;
    }

}

到这里就构建了核心的拦截链

  • 开启链路调用
//开启链路调用
chain.entry(context, resourceWrapper, null, count, prioritized, args);

开始执行拦截链逻辑,这个我们后续分析

YOLOv8 交通流量监测详解 本文介绍了一个基于YOLOv8的交通流量监测系统,该系统通过深度学习技术实现车辆实时检测、跟踪和分类。系统核心功能包括:1)使用YOLOv8模型检测道路车辆并进行持续跟踪;2)按方向和车型统计车流量;3)支持多区域流量监测和数据可视化。文章提供了完整的代码实现示例,涵盖基础车辆检测、视频流处理和高级数据分析功能。系统还可进一步优化性能,如使用轻量级模型、GPU加速等,并建议扩展车速估算、密度分析等功能。该方案为交通管理提供了有效的实时监测和决策支持工具。 阅读详情

相关推荐

微信群消息监控系统实战:从零搭建Python自动化监控平台

本文详细介绍了如何从零搭建Python微信群消息监控系统,实现自动化监控和记录群消息。通过wxauto库模拟人工操作微信,结合MySQL数据库存储和智能去重策略,系统能高效处理大量消息并支持关键词监控。文章还分享了性能优化、安全合规等实战经验,帮助开发者快速构建高效稳定的监控平台。

weixin_29091105的博客 319

Sentinel源码分析

Sentinel源码分析 1.Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能,本质要做的就是两件事情: 统计数据:统计某个资源的访问数据(QPS、RT等信息) 规则判断:判断限流规则、隔离规则、降级规则、熔断规则是否满足 这里的资源就是希望被Sentinel保护的业务,例如项目中定义的controller方法就是默认被Sentinel保护的资源。 1.1.ProcessorSlotChain 实现上述功能的核心骨架是一个叫做ProcessorSlotChain的类。这个类基

学过的东西,讲不出来等于没学。 5755

某银行大数据分析平台之云原生架构

软考架构师论文

doudoudouy的博客 768

sentinel源码分析

为什么需要sentinel 微服务架构,但服务之间存在很强的依赖,如何避免下层服务挂掉后,不影响上层服务呢? 如何防止雪崩呢? 秒杀场景,服务器的性能都是有上线的,如何避免大流量,高并发的请求不拖垮服务,并返回给用户友好的界面反馈呢? 示例 客户端代码,使用了限流的get请求,并抛出异常 @RestController @RequestMapping("/sentinel") public class SentinelController { static { // 初始化规则

FourZeroZero's home 1914

协方差矩阵

对两个类内协方差矩阵进行对角化,可以将它们变换为对角矩阵。这个过程可以通过对每个协方差矩阵进行特征值分解来实现,从而得到它们的特征向量和特征值,进而得到它们的对角矩阵形式。这个过程的意义在于,它可以帮助我们找到一个新的坐标系,使得在这个坐标系下,每个特征之间都是独立的,从而简化了计算。具体来说,当我们使用对角协方差矩阵作为特征向量的坐标系时,它意味着每个特征之间都是相互独立的,从而方便了进一步的分析和处理。在实际应用中,对角化协方差矩阵可以用于降维、特征选择和分类等任务。

m0_55196097的博客 1万+

IQA图像质量评价 数据集介绍(LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K)

LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K 数据集介绍

qq_37925923的博客 1万+

Spring Cloud Alibaba - Sentinel源码分析(一)

Sentinel是分布式系统的防御系统。以流量为切入点,通过动态设置的流量控制、服务熔断等手段达到 保护系统的目的,通过服务降级增强服务被拒后用户的体验。在 Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry。Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建;每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain)。资源操作时的上下文环境一次资源操作Sentinel 将。

杀神lwz的博客 1832

CoppeliaSim和Python进行无人机联合仿真

CopeeliaSim和Python进行无人机轨迹跟踪联合仿真。首先建立起CoppeliaSim和Python的连接,其次在Python中生成轨迹,CoppeliaSim仿真环境中的无人机进行跟踪,并绘制出轨迹曲线,有每一步详细的教学。

加斯顿工程师的博客 986

Sentinel源码

一、概述 在SpringBoot启动过程中,会加载外部依赖中META-INF/spring.factories声明的类。其中最重要的两个类分别为SentinelWebAutoConfiguration和SentinelAutoConfiguration。下面针对这两个类进行分析,逐渐深入理解流量是如何被Sentinel拦截的。 图1 spring.factories 二、深入理解 2.1 SentinelAutoConfiguration package com.alibaba.cloud.sentin

m0_45406092的博客 1106

元宇宙通证- 九、IT/ICT发展史全景长图

九、IT/ICT发展史全景长图 (一)综述 IT是Information Technology的缩写,意为”信息技术“,包含现代计算机、网络、通信等信息领域技术。自1844年人类历史上发出来第一份电报,实现了信息的长图传输,信息技术发展的历史大幕随之拉开。信息技术的普遍应用,是进入信息社会的标志。 IT技术最早发源于半导体,然后发展处计算机、通信网和互联网,进而演进到现在的AI、XR、计算机、大数据、物联网、工业互联网、区块链、量子计算等。 有人说元宇宙是下一代互联网,有人说元宇宙是互联网的终极形态。 我们

沧海之巅的专栏 1万+

C#项目实战——YModem协议文件传输【实例】

1、先由上位机发送*update*的握手信号,下位机返回响应字符‘C’(字符C,ASII码为0x43),之后通信双方开始以YMODEM协议进行数据通信。2、 YMODEM协议格式说明(1)起始帧数据格式帧类型(1byte)帧序号帧序号反码传输的文件名文件大小数据CRCSOH00FFfilenamefileziseNULCRCSOH=0x01,表示这个数据帧中包含着128个字节的数据(STX表示1024字节,初始帧只有128个);00表示数据帧序号,初始是0,依次向下排。

做有价值的事,积累有价值的笔记! 3654

Sentinel核心源码解析

Sentinel核心源码解析 Sentinel是分布式系统的防御系统。以流量为切入点,通过动态设置的流量控制、服务熔断等手段达到保护系统的目的,通过服务降级增强服务被拒后用户的体验。 一、Sentinel工作原理 1 架构图解析 若要读懂Sentinel源码,则必须要搞明白官方给出的Sentinel的架构图。 Sentinel的核心骨架是ProcessorSlotChain。其将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能组合在一起(限流、降级、系统保护)。系统会为每个资源创建一套S

qq_24101357的博客 1万+

把 SM30 用顺:从表设计到权限与传输,全面掌握 SAP Table Maintenance Generator

摘要 SAP的Table Maintenance Generator(TMG)是为配置表维护需求设计的经典工具,能够生成标准化的维护对话框(SM30)。它支持单表、维护视图(多表关联)和视图簇(导航式维护)三种维护对象类型。使用TMG前需注意三个关键设置:1)表维护权限选项;2)交付类(决定数据传输行为);3)客户端字段配置。通过SE54/SE11生成维护对话框时,需选择维护类型(一步/两步)和记录例程(控制传输)。TMG生成的对象包含函数组、屏幕和处理模块,但部分标准框架不可修改。实际应用中,可通过参数事

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 176

03、Sentinel 源码分析 之 Hello World

欢迎来到 Sentinel 的世界!这篇新手指南将指引您快速入门 Sentinel。 Sentinel 的使用可以分为两个部分: 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。 1、引入 Sentinel 依赖 如果您的应用使用了 Maven,则在 pom.xml

carl.zhao的专栏 483

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

04、Sentinel 源码分析 之 规则加载

从上面的一篇文章中 – 03、Sentinel 源码分析 之 Hello World 我们知道了如何简单的使用 Sentinel 进行限流工作。如果你想知道更加详细的使用方式可以查询 Sentinel 的官方文档。我们首先来回顾一下之前的简单操作,然后就来从源码级别来分析一下这个框架是如何实现的。 1、Sentinel 简单操作 下面就是使用 Sentinel 框架进行资源限流的简单步骤。 public static void main(String[] args) { // 配置规则. i

carl.zhao的专栏 983

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

高可用之限流-06-slide window 滑动窗口 sentinel 源码

1、现在假设当前时间是2018-12-15 14:30:00,对应毫秒是:1544855400000ms,所以timeId = 1544855400000 / 500为:3089710800,对应的idx为0,窗口开始时间time为 time - time % windowLengthInMs还是1544855400000;如果当前窗口的开始时间time大于old的开始时间,则说明old窗口已经过时了,将old的开始时间更新为最新值:time;6、由于是新的时间窗口,old为空,则重新创建。

1044

RuoYi-Vue-Plus 与 RuoYi-Cloud-Plus 高端进阶 源码分析 系列教程

高端进阶 源码分析 系列教程

李虹柏的博客 6万+

最新通俗易懂的阿里Sentinel源码分析:如何向控制台发送心跳包?,三面拼多多

总的来说,面试是有套路的,一面基础,二面架构,三面个人。最后,小编这里收集整理了一些资料,其中包括面试题(含答案)、书籍、视频等。希望也能帮助想进大厂的朋友本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取。

2401_84584873的博客 1061

Sentine 源码分析之--AuthoritySlot、SystemSlot、GatewayFlowSlot

上一篇我对 Sentinel 中统计数据部分的 NodeSelectorSlot、ClusterBuilderSlot、StatisticSlot 的相关源码进行了分析,本篇我们开始分析规则相关的源码。

weixin_42118323的博客 1309

2021-09-03

这里写自定sentinel源码欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 学nm个锤子 2021-03-07 21:59:49 106 已收藏 1 分类专栏: cloud 文章标签:

dh1636的博客 213

nacos 负载策略_[微服务] 最新Spring Cloud中的负载均衡策略-Nacos+Sentinel+OpenFeign实战...

简介来自大厂最新的Spring Cloud的高级实战课程,课程内容的经验总结均来自于一线大厂的全新技术,课程内容涵盖了最新的RoundRobinRule负载均衡实战策略,Ribbon默认负载轮训算法原理和源码分析。Nacos动态发现,Sentinel高可用,OpenFeign实战,Nacos集群配置,Seata分布式事务中间件,OpenFeign增强课程,Hystrix服务实战,GateWay实战...

weixin_28801391的博客 846

【2022】软件笔录&&日记

【一月份笔录】 2022-01-01 Sentinel基础使用 2022-01-02 Sentinel源码分析 Sentinel与Springboot的整合方法 责任链设计模式 这条责任链是如何构造而成的 每个槽位的大概职责 源码入口 自动配置类SentinelAutoConfiguration -> SentinelResourceAspect(注意这个类是AOP切面类,使用了环绕通知) -》SphU.entry方法 -〉构造责任链 -》依次调用链子上的每一个槽位 ...

qq_37023928的博客 388

微服务笔记合集

SpringCloud01 Nacos安装指南 SpringCloud实用篇02 Nacos集群搭建 Docker实用篇 安装Docker RabbitMQ RabbitMQ部署指南 分布式搜索引擎01 分布式搜索引擎02 分布式搜索引擎03 安装elasticsearch 微服务保护 Jmeter快速入门 sentinel规则持久化 分布式事务 seata的部署和集成 分布式缓存 Redis集群 安装Canal 安装OpenResty 案例导入说明 RabbitMQ-高级篇 RabbitMQ部署指南2 微

学过的东西,讲不出来等于没学。 2561

Spring Cloud 系列文章·索引贴

点击上方"IT牧场",选择"设为星标"技术干货每日送达!本文列出笔者所有Spring Cloud相关的文章。共计80+篇,包括系列教程、新特性总结、技巧 & 提升...

ITMuch的专栏 231

redission分布式锁实现_利用Redisson实现分布式锁

作者:bravobantech.lede.com/2017/03/08/rd/server/Redisson针对项目中使用的分布式锁进行简单的示例配置以及源码解析,并列举源码中使用到的一些基础知识点,但是没有对redisson中使用到的netty知识进行解析。本篇主要是对以下几个方面进行了探索Maven配置RedissonLock简单示例源码中使用到的Redis命令源码中使用到的lua...

weixin_39613548的博客 267

redisson的锁的类型_Redisson 是如何实现分布式锁的?

作者 |bravoban来源 |tech.lede.com/2017/03/08/rd/server/Redisson针对项目中使用的分布式锁进行简单的示例配置以及源码解析,并列举源码中使用到的一些基础知识点,但是没有对redisson中使用到的netty知识进行解析。本篇主要是对以下几个方面进行了探索Maven配置RedissonLock简单示例源码中使用到的Redis命令源码中使...

weixin_34549315的博客 130

微服务(Microservice)系列文章

文章目录Microservice1. SpringBoot2.1 基本概念2.2 应用分析2.3 源码分析2.3.1 核心流程源码分析2.3.2 注解源码分析2.3.3 扩展类源码分析2.3.4 关键机制源码分析2.4 问题分析2. SpringCloud2.1 Eureka2.2 LoadBalancer2.3 Feign2.4 Hystrix3. SpringCloudAlibaba3.1 Nacos3.2 Sentinel4. Dubbo4.1 基本介绍4.2 基本应用4.3 源码分析 Microse

bigdata-page 371
上一篇: sentinel源码分析-02客户端处理服务端下发请求
下一篇: sentinel源码分析-04核心概念介绍
胖柯G
博客等级 码龄10年 453粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值