首页 > 编程语言 > Sentinel系列之SlotChain、NodeSelectorSlot、ClusterBuilderSlot分析

Sentinel系列之SlotChain、NodeSelectorSlot、ClusterBuilderSlot分析

时间:2023-10-04 17:45:14浏览次数:48  
标签:调用 String rule1 SlotChain ClusterBuilderSlot static void Sentinel public

本文基于Sentinel 1.8.6版本分析

1. SlotChain

我们从入口com.alibaba.csp.sentinel.SphU#entry(java.lang.String) 开始分析。

一路走读下来,会进入到这个方法com.alibaba.csp.sentinel.CtSph#lookProcessChain,查找该资源对应的Slot Chain。

image

接下来看如何构建这个Slot Chain. Sentinel实现了自己的一套SPI机制,提供了缓存和排序等功能。在@Spi注解上有一个order字段,支持按order从小到大排序。

image

image

2. Slot

插槽的接口叫ProcessorSlot,它有4个方法,分别对应入口、出口时自己运行逻辑及调用下一个Slot的入口或出口。

image

Slot Chain也是插槽的一个实现,作为链条的入口 ,比较特殊的点在于它持有了其他的Slot。

image

2.1. NodeSelectorSlot

NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;

image

首先了解一下Node的类继承关系

image

有三种不同的节点:

Root: 根节点,全局唯一,所有调用的入口,值固定为machine-root,承载在com.alibaba.csp.sentinel.Constants#ROOT字段。它的实现类是EntranceNode.

EntranceNode:DefaultNode的子类,入口节点,一个Context会有一个入口节点,用于统计当前Context的总体流量数据,统计维度为Context。可以调用com.alibaba.csp.sentinel.context.ContextUtil#enter(java.lang.String)设置,若无设置,默认值为sentinel_default_context。它的实现类也是EntranceNode.

DefaultNode:默认节点,用于统计一个resource在当前Context中的流量数据,DefaultNode持有指定的Context和指定的Resource的统计数据,意味着DefaultNode是以Context和Resource为维度的统计节点。它的实现类是DefaultNode.

通过这个调用链路,就可以实现基于调用链路限流。

public class ChainStrategyDemo {

    private static final String RESOURCE_1 = "Resource1";

    private static final Logger logger = LoggerFactory.getLogger(ChainStrategyDemo.class);

    public static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        // 绑定资源
        rule1.setResource(RESOURCE_1);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 可以只对某个链路生效
        rule1.setCount(2);
        rule1.setStrategy(RuleConstant.STRATEGY_CHAIN);
        rule1.setRefResource("context1");
        rules.add(rule1);

        FlowRuleManager.loadRules(rules);
    }

    public static void method(String contextName) {
        // 定义资源
        try(Entry entry = SphU.entry(RESOURCE_1)){
            logger.info("Visit resource 1");
        }catch (BlockException e) {
            logger.error("{} 被流控了!", contextName);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        initFlowRules();

        ExecutorService executor = Executors.newFixedThreadPool(2);

        executor.submit(new Task("context1"));

        executor.submit(new Task("context2"));

        Thread.sleep(10_000L);
        executor.shutdown();
    }

    public static class Task implements Runnable{

        private String contextName;

        public Task(String contextName) {
            this.contextName = contextName;
        }

        @Override
        public void run() {
            ContextUtil.enter(contextName);
            for(int i = 0; i <= 4; i++){
                method(contextName);
            }
        }
    }

}

通过上面的分析,可以得出如下的调用链路。

image

使用Debug方式,在调用完成后,查看内存中的调用链路

image

运行结果,只对context1限流

image

需要注意的是,这里的调用关系并不是代码的调用链路,而是关注调用入口和资源的关系。

再来看下面这个例子,method2嵌套了method1。

	public static void main(String[] args) throws InterruptedException {
        initFlowRules();

        method1();

        method2();

        System.out.println("Finished!");
    }

    public static void method1() {
        // 定义资源
        try(Entry entry = SphU.entry(RESOURCE_1)){
            System.out.println("Visit resource 1");
        }catch (BlockException e) {
            System.out.println("被流控了!");
        }
    }

    public static void method2() {
        // 定义资源
        try(Entry entry = SphU.entry(RESOURCE_2)){
            System.out.println("Visit resource 1");
            method1();
        }catch (BlockException e) {
            System.out.println("被流控了!");
        }
    }

image

2.2 ClusterBuilderSlot

如果想要以资源的维度来限流,那么必须对调用链路的DefaultNode,以资源的维度做一次汇总,ClusterBuilderSlot正是这个作用。

此插槽用于构建资源ClusterNode 以及调用来源节点。ClusterNode 保持资源运行统计信息(响应时间、QPS、block 数目、线程数、异常数等)以及原始调用者统计信息列表。来源调用者的名字由 ContextUtil.enter(contextName,origin) 中的 origin 标记。

ClusterNode: 资源唯一标识的 ClusterNode 的 runtime 统计。它的实现类是ClusterNode.

Origin: 根据来自不同调用者的统计信息,在ClusterNode中有一个Map,专门按Origin调用来源统计不同的数据,默认是空字符串。在访问资源前,可以通过com.alibaba.csp.sentinel.context.ContextUtil#enter(java.lang.String, java.lang.String)指定调用来源。它的实现类是StatisticNode.

image

所以,完整的关系图如下,绿色表示这些节点存储了不同维度的统计数据

image

通过LimitApp,就可以实现基于调用来源的限流。

	public static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule1 = new FlowRule();
        // 绑定资源
        rule1.setResource(RESOURCE_1);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 可以只对某个来源生效
        rule1.setCount(2);
        // 默认也是这个值
        rule1.setStrategy(RuleConstant.STRATEGY_DIRECT);
        rule1.setLimitApp(DEFAULT_LIMIT_APP);
        rules.add(rule1);

        FlowRuleManager.loadRules(rules);
    }

    public static void method(String origin) {
        // 定义资源
        try (Entry entry = SphU.entry(RESOURCE_1)) {
            logger.info("Visit resource 1");
        } catch (BlockException e) {
            logger.error("{} 被流控了!", origin);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        initFlowRules();

        ExecutorService executor = Executors.newFixedThreadPool(2);

        executor.submit(new Task(DEFAULT_LIMIT_APP));

        executor.submit(new Task("AnotherLimitApp"));

        Thread.sleep(10_000L);
        executor.shutdown();
    }

    public static class Task implements Runnable {

        private String origin;

        public Task(String origin) {
            this.origin = origin;
        }

        @Override
        public void run() {
            for (int i = 0; i <= 4; i++) {
                ContextUtil.enter(DEFAULT_ENTRANCE, origin);
                method(origin);
            }
        }
    }

image

通过上面的介绍,我们知道了有不同的Node,并且流量控制有不同的策略Strategy,还有可以通过调用来源来限制,那么不同的情况下会使用什么节点进行限流判断呢?

在进行限流判断前,会调用这个方法选择合适的节点 com.alibaba.csp.sentinel.slots.block.flow.FlowRuleChecker#selectNodeByRequesterAndStrategy

image

image

调用来源/策略 Direct Relate Chain
指定来源 origin cluster current(当前节点就是链路第三层的DefaultNode)
不指定来源 cluster cluster current(当前节点就是链路第三层的DefaultNode)
指定来源之外(Other,其实也是指定来源) origin cluster current(当前节点就是链路第三层的DefaultNode)

可以看到,如果选择了Chain基于链路限流,则肯定是使用当前节点,无法指定来源;如果选择了Relate基于关联关系,则肯定是使用cluster; 如果选择了Direct,就要看有没有指定来源,若指定了则使用origin,否则还是使用cluster.

标签:调用,String,rule1,SlotChain,ClusterBuilderSlot,static,void,Sentinel,public
From: https://www.cnblogs.com/kingsleylam/p/17742511.html

相关文章

  • Sentinel
    目录雪崩问题雪崩问题微服务调用链路中的某个服务故障满,引起整个链路中的所有微服务都不可用,这就是雪崩。解决方案:1.超时处理:设定超时时间,请求一定时间没有响应就返回错误信息,不会无休止等待2.舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔......
  • springboot整合sentinel,sleuth
     1. 整合sentinel流控当需要对一个接口进行流量监控时可以使用springboot整合sentinel  (1)在common模块中导入依赖spring-cloud-starter-alibaba-sentinel;  (2)下载sentinel控制台并启动;  (3)配置sentinel控制台地址信息spring.cloud.sentinel.transport.dashboa......
  • Sentinel系列之流量控制及熔断降级示例
    关于Sentinel的介绍网上很多,不再复制粘贴。本文主要演示Sentinel的两个重点功能:流量控制和熔断降级。示例基于Sentinel1.8.6, 同时使用JMeter进行并发请求(Postman无法并发)。当然也可以通过main方法,但这样就无法重复触发,并且无法学习Sentinel与Spring框架的集成另外需要注意的......
  • 熔断、限流、降级 —— SpringCloud Alibaba Sentinel
    Sentinel简介Sentinel是阿里中间件团队开源的,面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性Sentinel提供了两个服务组件:Sentinel用来实现微服务系统中服务熔断......
  • Redis之Sentinel哨兵监控
    哨兵简介 1.redis提供了哨兵的命令,是一个独立的进程 2.哨兵通过发送命令给节点,通过redis节点响应达到监控多个redis实例的运行情况 3.当哨兵发现master宕机,会自动将从节点切换成主节点,并通知其他的从节点,修改配置文件切换主机 4.默认端口是26379哨兵的主要任务 1.......
  • Redis主从架构环境搭建(一主二从 + 3个sentinel)
    安装RedisServersudoadd-apt-repositoryppa:redislabs/redissudoaptupdatesudoaptinstallredis-serverredis-cli-h127.0.0.1-p6379pingsudosystemctlrestartredis-serverss-an|grep6379redis-server-vRedisserverv=7.0.12sha=00000000:0malloc=jem......
  • 基于 COLA 架构的 Spring Cloud Alibaba(四)整合 Sentinel
    在上一篇中,我们介绍了在项目中如何整合Nacos、OpenFeign。这一篇,我们来介绍一下项目中Sentinel的整合。1.关于SentinelSentinel是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。Sentinel的使......
  • Sentinel(二)网关流控配置
    Sentinel(二)网关流控​ 官网介绍:https://github.com/alibaba/Sentinel/wiki/网关限流1引入依赖<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>......
  • Sentinel(一)Sentinel简介
    Sentinel(一)Sentinel简介1高并发系统关注的问题服务单一职责+独立部署:秒杀服务即使自己扛不住压力,挂掉,也不要影响别人秒杀链接加密:防止恶意攻击,模拟秒杀请求1000次/秒攻击;防止链接暴露,防止自己工作人员提前秒杀商品库存预热+快速扣减:无需每次进行实时校验,库存预热放到r......
  • Sentinel(四)工作原理和源码解析总结
    Sentinel工作原理和源码解析1工作原理简介Sentinel在使用上是通过注解@SentinelResource来实现的对资源的流控保护的,本质是通过AOP的方式来实现的流控方法增强,底层是通过SentinelResourceAspect指定切入点为注解,然后通过环绕通知的方式获取注解传来的资源名称,然后调用Sentine......