sentinel 随笔 2-流控

news2024/12/23 13:31:23

0. 想要个半个月的旅游

最近发现算法比较有意思一些,什么企业框架都是看不完的…


书接 FlowSlot

1. FlowRuleChecker.checkFlow() : 配置的规则校验类

sentinel 并没有对这个Checker进行抽象的设计,第一次看有些别扭…

package com.alibaba.csp.sentinel.slots.block.flow;

/**
 * Rule checker for flow control rules.
 */
public class FlowRuleChecker {

    public void checkFlow(Function<String, Collection<FlowRule>> ruleProvider, ResourceWrapper resource,
                          Context context, DefaultNode node, int count, boolean prioritized) throws BlockException {
        if (ruleProvider == null || resource == null) {
            return;
        }
		// 根据给定的资源名,获取对应的规则(即 DefaultController、RateLimiteController这些)
        Collection<FlowRule> rules = ruleProvider.apply(resource.getName());
        if (rules != null) {
            for (FlowRule rule : rules) {
				// step into ...
                if (!canPassCheck(rule, context, node, count, prioritized)) {
                    throw new FlowException(rule.getLimitApp(), rule);
                }
            }
        }
    }

    public boolean canPassCheck(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node,
                                                    int acquireCount) {
		// step into ...
        return canPassCheck(rule, context, node, acquireCount, false);
    }

    public boolean canPassCheck(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node, int acquireCount,
                                                    boolean prioritized) {
        String limitApp = rule.getLimitApp();
        if (limitApp == null) {
            return true;
        }
		// 支持两种流控模式: 集群、本地
        if (rule.isClusterMode()) {
            return passClusterCheck(rule, context, node, acquireCount, prioritized);
        }

		// step into ...
        return passLocalCheck(rule, context, node, acquireCount, prioritized);
    }

    private static boolean passLocalCheck(FlowRule rule, Context context, DefaultNode node, int acquireCount,
                                          boolean prioritized) {
		// step into ...
		// 根据请求(指定的调用者)+策略 选择需要流控的节点实例
        Node selectedNode = selectNodeByRequesterAndStrategy(rule, context, node);
        if (selectedNode == null) {
            return true;
        }

		// step into ...
		// 调用TrafficShapingController实现类的流控算法
        return rule.getRater().canPass(selectedNode, acquireCount, prioritized);
    }

	static Node selectNodeByRequesterAndStrategy(/*@NonNull*/ FlowRule rule, Context context, DefaultNode node) {
        // The limit app should not be empty.
        String limitApp = rule.getLimitApp();
        int strategy = rule.getStrategy();
        String origin = context.getOrigin();

		// 如果规则指定的调用者(针对来源)非 default、其他
        if (limitApp.equals(origin) && filterOrigin(origin)) {
			// 直接策略: 直接对来源节点进行流控
            if (strategy == RuleConstant.STRATEGY_DIRECT) {
                // Matches limit origin, return origin statistic node.
                return context.getOriginNode();
            }
			// step into ...
			// 反之则是 关联、链路 管控
            return selectReferenceNode(rule, context, node);
        } 
		// 如果规则未指定的调用者(针对来源),即 default
		else if (RuleConstant.LIMIT_APP_DEFAULT.equals(limitApp)) {
			// 此时的直接策略: 对其集群节点管控
            if (strategy == RuleConstant.STRATEGY_DIRECT) {
                // Return the cluster node.
                return node.getClusterNode();
            }

			// 同上,走关联、链路 管控
            return selectReferenceNode(rule, context, node);
        } 
		// 调用则:其他
		else if (RuleConstant.LIMIT_APP_OTHER.equals(limitApp)
            && FlowRuleManager.isOtherOrigin(origin, rule.getResource())) {
			// 直接策略:对其来源节点管控
            if (strategy == RuleConstant.STRATEGY_DIRECT) {
                return context.getOriginNode();
            }
			// 同上
            return selectReferenceNode(rule, context, node);
        }

        return null;
    }
	
	private static boolean filterOrigin(String origin) {
        // Origin cannot be `default` or `other`.
        return !RuleConstant.LIMIT_APP_DEFAULT.equals(origin) && !RuleConstant.LIMIT_APP_OTHER.equals(origin);
    }
	
	static Node selectReferenceNode(FlowRule rule, Context context, DefaultNode node) {
        String refResource = rule.getRefResource();
        int strategy = rule.getStrategy();

        if (StringUtil.isEmpty(refResource)) {
            return null;
        }

		// 可以看出来,这个方法不仅仅支持 关联模式(策略),还支持 链路模式 
		// 关联模式,取其 ClusterNode 集群节点
        if (strategy == RuleConstant.STRATEGY_RELATE) {
            return ClusterBuilderSlot.getClusterNode(refResource);
        }

		// 链路模式,如果存在,直接取当前节点
        if (strategy == RuleConstant.STRATEGY_CHAIN) {
            if (!refResource.equals(context.getName())) {
                return null;
            }
            return node;
        }
        // No node.
        return null;
    }
}

2. 为了更加生动一些,这里补充一些dashboard的配置

请添加图片描述

  • 资源名: resource的name
  • 针对来源: 服务调用方,即 origin
  • 阈值类型:即 grade 整型变量指代
  • 单机阈值: 即 左边所选的 阈值类型 对应的阈值数值
  • 是否集群: FlowRuleChecker的passLocalCheck()、passClusterCheck()提供支持,如果集群流控突然挂掉,将自动切换成本地的流控支持
  • 流控模式:将决定访问流量的审计、管控的节点
  • 流控效果:这里即我们前面提及的算法部分

实现 流控效果 的XxxController ,请移步 流控 随笔 0-算法

2.1 规则常量


package com.alibaba.csp.sentinel.slots.block;

public final class RuleConstant {

	// 阈值类型
    public static final int FLOW_GRADE_THREAD = 0;
    public static final int FLOW_GRADE_QPS = 1;

	// 降级配置
    public static final int DEGRADE_GRADE_RT = 0;
    /**
     * Degrade by biz exception ratio in the current {@link IntervalProperty#INTERVAL} second(s).
     */
    public static final int DEGRADE_GRADE_EXCEPTION_RATIO = 1;
    /**
     * Degrade by biz exception count in the last 60 seconds.
     */
    public static final int DEGRADE_GRADE_EXCEPTION_COUNT = 2;

    public static final int DEGRADE_DEFAULT_SLOW_REQUEST_AMOUNT = 5;
    public static final int DEGRADE_DEFAULT_MIN_REQUEST_AMOUNT = 5;

	// 规则支持配置 黑白名单
    public static final int AUTHORITY_WHITE = 0;
    public static final int AUTHORITY_BLACK = 1;

	// 流控策略(流控模式)
    public static final int STRATEGY_DIRECT = 0;
    public static final int STRATEGY_RELATE = 1;
    public static final int STRATEGY_CHAIN = 2;

	// 流控行为(流控效果)
    public static final int CONTROL_BEHAVIOR_DEFAULT = 0;
    public static final int CONTROL_BEHAVIOR_WARM_UP = 1;
    public static final int CONTROL_BEHAVIOR_RATE_LIMITER = 2;
    public static final int CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER = 3;

    public static final int DEFAULT_BLOCK_STRATEGY = 0;
    public static final int TRY_AGAIN_BLOCK_STRATEGY = 1;
    public static final int TRY_UNTIL_SUCCESS_BLOCK_STRATEGY = 2;

    public static final int DEFAULT_RESOURCE_TIMEOUT_STRATEGY = 0;
    public static final int RELEASE_RESOURCE_TIMEOUT_STRATEGY = 1;
    public static final int KEEP_RESOURCE_TIMEOUT_STRATEGY = 2;

	// 针对特定的调用者的规则
    public static final String LIMIT_APP_DEFAULT = "default";
    public static final String LIMIT_APP_OTHER = "other";

    public static final int DEFAULT_SAMPLE_COUNT = 2;
    public static final int DEFAULT_WINDOW_INTERVAL_MS = 1000;

    private RuleConstant() {}
}

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

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

相关文章

01- 综述 (目标检测)

要点&#xff1a; 区分One-stage detector 和 Two-stage detector 参考链接&#xff1a;深度学习目标检测最全综述 - 爱码网 详细模型解读参考&#xff1a;目标检测简介 - 知乎 一 目标检测分类 1.1 发展历程 检测网络发布历程&#xff1a; 1.2 检测模型分类 2014年后目标…

C嘎嘎~~ [类 下篇之运算符重载]

类 下篇 之运算符重载 5.赋值运算符重载5.1运算符重载5.1.1 运算符的概念5..1.2 重载运费符的位置5.1.3运算符重载的实质 5.2 赋值运算符重载5.2.1深刻理解---编译器生成的默认赋值运算符重载5.2.2深刻理解---拷贝构造和赋值运算符重载5.2.3深刻理解---传参和返回值用引用修饰…

CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some

问题描述&#xff1a; 在修改代码时&#xff0c;出现入下报错。 发生异常: RuntimeError CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. For debuggi…

Android Switch开关按钮使用和自定义样式(系列教程五)

Switch开关按钮简介 Switch开关按钮是Android中的基本控件之一&#xff0c;其本质上也是一个按钮&#xff0c;具有开和关两种展示状态。 Switch开关按钮基本使用 在布局文件中定义开关按钮&#xff1a; <LinearLayoutandroid:layout_width"300dp"android:layo…

Vivado安装后添加器件库

1.前言 通常安装Vivado时&#xff0c;由于软件完整安装的空间需求过于庞大&#xff0c;一般只会选择一部分器件进行安装。而随着学习和工作的进展&#xff0c;遇到新的赛灵思朋友是成长的里程碑&#xff0c;也是综合不能通过的绊脚石。 今天有幸认识了一位新的赛灵思朋友——…

云原生: istio+dapr构建多运行时服务网格

2020 年&#xff0c;Bilgin Ibryam 提出了 Multi-Runtime&#xff08;多运行时&#xff09;的理念&#xff0c;对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华。那到底什么是多运行时呢&#xff1f;首先还是得从分布式应用的四大类基本需求讲起。简单来讲任何分布…

刷题练习3

文章目录 题目一分析题解 题目二分析第一种第二种 题解第一种方法代码第二种方法代码 题目一 题目链接 描述 读入一个字符串str&#xff0c;输出字符串str中的连续最长的数字串 输入描述&#xff1a; 个测试输入包含1个测试用例&#xff0c;一个字符串str&#xff0c;长度不超…

牛顿迭代法解超越方程

牛顿迭代法解超越方程 L g T 2 2 π t a n h ( 2 π L d ) L\frac{gT^2}{2\pi}tanh(\frac{2\pi}{L}d) L2πgT2​tanh(L2π​d) 方程&#xff1a; f ( L ) L − g T 2 2 π t a n h ( 2 π L d ) 0 f(L)L-\frac{gT^2}{2\pi}tanh(\frac{2\pi}{L}d)0 f(L)L−2πgT2​tanh(L2π…

~项目启动~

rmq是什么&#xff1f; "rmq" 可能指的是 "RabbitMQ"&#xff0c;它是一种开源消息队列软件&#xff0c;采用 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;协议&#xff0c;可以用于支持异步处理、任务分发、解耦合等应用场景。Rabbit…

仪表检测与读数(一):仪表检测

基于YOLOv4的仪表检测 前言YOLOv4源码下载数据集处理与模型训练模型性能测试 前言 本系列是想记录一下自己实现的一种用于仪表检测与读数的方法&#xff0c;首先方法仅针对于单指针仪表和单行显示的数字仪表进行了检测与读数方法的设计。方法的整体思路是&#xff1a;第一步对拍…

[ 云计算 | Azure ] Chapter 06 | 计算服务之虚拟机、虚拟机规模集、Azure 容器、Azure App 与 Azure Functions

本系列已经更新文章列表&#xff08;已更新&#xff09;&#xff1a; [ Azure 云计算从业者 ] Chapter 03 | 描述云计算运营中的 CapEx 与 OpEx&#xff0c;如何区分 CapEx 与 OpEx[ Azure 云计算从业者 ] Chapter 04 | Azure核心体系结构组件之数据中心、区域与区域对、可用区…

【Qt】插件Plugin入门之Q_PLUGIN_METADATA()宏【2023.05.07】

摘要 分析Q_PLUGIN_METADATA宏的设计意图&#xff0c;站在设计者的意图进行插件的高屋建瓴式学习。 Meta-Object Compiler 简称MOC Qt 的 Meta-Object Compiler&#xff08;MOC&#xff09;是一个预处理器&#xff0c;用于处理带有特殊关键字的 C 文件&#xff0c;并生成用于…

Linux命令·netstat

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据&#xff0c;一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序&#xff0c;它能提供TCP连接&#xff0c;TCP和UDP监听&#xff0c;进程内存管理的相关报告。 如果你的计算机有时候…

详细版简单易学版TypeScript各类型声明

假如本地新建了一个b.ts文件 安装TypeScript&#xff1a;npm install -g typescript 编译代码&#xff1a;tsc b.ts 运行js&#xff1a;node b.js 在终端输入 tsc -init 生成 tsconfig.json 文件 类型注解&#xff1a;TypeScript里的类型注解是一种轻量级的为函数或变量添加约束…

Python中模块和包基础学习

目录 模块 引入模块 使用from...import语句引入模块中的指定变量或函数 使用import...as语句给模块起别名 使用dir()函数查看模块中的所有变量和函数 使用__name__变量判断模块是被导入还是直接执行 包 注意 示例 模块 Python中的模块是指一个文件&#xff0c;可以包…

2.1 掌握NumPy数组对象ndarray

2.1 掌握NumPy数组对象ndarray 2.2.1 创建数组对象1&#xff0e;数组创建2&#xff0e;数组属性&#xff1a;ndarray&#xff08;数组&#xff09;是存储单一数据类型的多维数组。3&#xff0e;数组数据类型 2.1.2 生成随机数random模块常用随机数生成函数 2.1.3 通过索引访问数…

Python中异常处理的学习

目录 异常的基本介绍 异常处理语句 抛出异常 异常的基本介绍 在Python中&#xff0c;如果程序出现错误&#xff0c;会抛出异常。异常是一种Python对象&#xff0c;它封装了错误的信息&#xff0c;并提供了一种处理错误的机制。Python中内置了很多异常类型&#xff0c;包括但…

C语言-学习之路-07

C语言-学习之路-07 内存管理作用域局部变量静态&#xff08;static&#xff09;局部变量全局变量extern全局变量声明全局函数和静态函数 内存分布内存分区 内存管理 作用域 C语言中变量的作用域可分为&#xff1a;代码作用域、函数作用域、文件作用域 局部变量 局部变量也叫…

C嘎嘎~~ [类 下篇(2)]

类 下篇2 5.赋值运算符重载5.1运算符重载5.1.1 运算符的概念5..1.2 重载运费符的位置5.1.3运算符重载的实质 5.2 赋值运算符重载5.2.1深刻理解---编译器生成的默认赋值运算符重载5.2.2深刻理解---拷贝构造和赋值运算符重载5.2.3深刻理解---传参和返回值用引用修饰 5.赋值运算符…

ADAS-透视前方:汽车HUD技术原理解析

“ 当人们谈论未来的汽车技术时&#xff0c;汽车HUD&#xff08;Head-Up Display&#xff09;是一个经常被提及的技术。HUD是一种驾驶辅助技术&#xff0c;它可以将关键的驾驶信息直接显示在驾驶员的视线范围内&#xff0c;让驾驶员无需转移视线就能获得所需信息。这个技术在过…