流量控制 Sentinel

news2024/11/15 23:50:39

一、Sentinel(哨兵)简介

1、Sentinel的功能及特点

1.Sentinel的功能
Sentinel的支持
 2.Sentinel的特点
Sentinel的特点

2、Sentinel的组成

核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 8 及以上的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。核心库不依赖控制台。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。提供了机器自发现、簇点链路自发现、监控、规则配置等功能。

3、Sentinel的内部结构及工作流程

1.内部核心类

1.Entry
每一次资源调用都会创建一个 Entry,包含了资源名、curNode(当前统计节点)、originNode(来源统计节点)等信息。

2.Context
Context是对资源操作的上下文,每个资源操作必须属于一个Context。如果代码中没有指定Context,则会创建一个name为sentinel_default_context的默认Context。一个Context生命周期中可以包含多个

3.Node
用于完成数据统计的接口
    1、StatisticNode:统计节点,是Node接口的实现类,用于完成数据统计.
    2、EntranceNode:入口节点,一个Context会有一个入口节点,用于统计当前Context的总体流量数据.
    3、DefaultNode:默认节点,用于统计一个资源在当前Context中的流量数据.
    4、ClusterNode:集群节点,用于统计一个资源在所有Context中的总体流量数据.

4.Slot
Slot中主要定义sentinel的功能,sentinel中默认提供了以下Slot
    1、NodeSelectorSlot
    负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降。
    2、ClusterBuilderSlot
    用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count,Block count,Exception count 等等,这些信息将用作为多维度限流,降级的依据。简单来说,就是用于构建ClusterNode。
    3、StatisticSlot
    用于记录、统计不同纬度的 runtime 指标监控信息。
    4、ParamFlowSlot
    对应控制台的:热点流控
    5、FlowSlot
    用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制。对应控制台的:流控规则
    6、AuthoritySlot
    根据配置的黑白名单和调用来源信息,来做黑白名单控制。对应控制台的:授权规则
    7、DegradeSlot
    通过统计信息以及预设的规则,来做熔断降级。对应控制台的:降级规则
    8、SystemSlot
    通过系统的状态,例如 load1 等,来控制总的入口流量。对应控制台:系统规则

5.ProcessSlotChain
Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起。

2.Sentinel设计和工作流程
Sentinel的核心骨架是 ProcessorSlotChain。
系统会为每个资源创建一套链路处理,将不同的 Slot(处理节点) 用责任链模式,将不同的功能组合在一起(限流、降级、系统保护)。
Sentinel的整体设计
Sentinel的工作流程

二、Sentinel(哨兵)使用

1、Sentinel 提供了多种定义资源方式

1.适配主流框架自动定义资源
2.通过 SphU 手动定义资源
3.通过 SphO 手动定义资源
4.注解方式定义资源

2、Sentinel控制台安装

下载地址: 
https://github.com/alibaba/Sentinel/releases
启动(用户名和密码默认 sentinel,用8080默认端口号)
java -jar sentinel-dashboard-1.8.2.jar  

3、代码使用

1.服务端引入依赖
<!-- Snetinel 依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
2、服务端配置修改
spring:
  application:
    name: jun-sentinel-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8800 #Nacos服务注册中心地址
    sentinel:
      transport:
        dashboard: localhost:8080 #配置Sentinel dashboard地址
        port: 8719
3.服务端启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudSentinelApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudAlibabaSentinelService8401Application.class, args);
    }
}
4、代码和控制台操作
控制台

熔断降级策略:

RT(平均相应时间,秒级)
当单位统计时长内,请求数目大于设置的最小请求数目,且慢调用的比例大于阈值。
异常比例(秒级)
当单位统计时长内,请求数目大于设置的最小请求数目且异常的比例大于阈值。
异常数(分钟级)
异常数(分钟级)超过阈值时,触发降级,时间窗口结束后关闭降级。

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class SentinelFlowLimitController {

    @Value("${server.port}")
    private String serverPort;

    /**
     * 通过 SphU 手动定义资源;try-catch 风格的 API。
     */
    @GetMapping("/testA")
    public String testA() {
        Entry entry = null;
        try {
            entry = SphU.entry("testAbySphU");
            //您的业务逻辑 - 开始
            log.info("服务访问成功------testA:" + serverPort);
            return "服务访问成功------testA:" + serverPort;
            //您的业务逻辑 - 结束
        } catch (BlockException e1) {
            //流控逻辑处理 - 开始
            log.info("testA 服务被限流");
            return "testA 服务被限流";
            //流控逻辑处理 - 结束
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
	}

    /**
     * 通过 SphO 手动定义资源;if-else 风格的 API。
     */
    @GetMapping("/testB")
    public String testB() {
        if (SphO.entry("testBbySphO")) {
            // 务必保证finally会被执行
            try {
                log.info("服务访问成功------testB:" + serverPort);
                return "服务访问成功------testB:" + serverPort;
            } finally {
                SphO.exit();
            }
        } else {
            // 资源访问阻止,被限流或被降级
            //流控逻辑处理 - 开始
            log.info("testB 服务被限流");
            return "testB 服务被限流";
            //流控逻辑处理 - 结束
        }
	}

	/**
     * 通过 @SentinelResource 注解定义资源。
     */
	@GetMapping("/testC")
	@SentinelResource(value = "testCbyAnnotation") //通过注解定义资源
	public String testC() {
		log.info("服务访问成功------testC:" + serverPort);
		return "服务访问成功------testC:" + serverPort;
	}

    /**
     * 通过 Sentinel 控制台定义流控规则
     */
    @GetMapping("/testD")
    @SentinelResource(value = "testD-resource", blockHandler = "blockHandlerTestD") //通过注解定义资源
    public String testD() {
        log.info("服务访问成功------testD:" + serverPort);
        return "服务访问成功------testD:" + serverPort;
    }

    /**
     * 限流之后的逻辑
     */
    public String blockHandlerTestD(BlockException exception) {
        log.info(Thread.currentThread().getName() + "TestD服务访问失败! 您已被限流,请稍后重试");
        return "TestD服务访问失败! 您已被限流,请稍后重试";
    }
}
5、纯代码控制接口
public abstract class CustomSentinelConfig {
    @PostConstruct
    private void config() {
        List<FlowRule> flowRules = new ArrayList<>();

        /**
         * 添加限流方式 10次拒绝访问
         */
        FlowRule flowRule1 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule1.setResource("限流-10");
        //限流阈值
        flowRule1.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule1.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule1.setControlBehavior(0);

        /**
         * 添加限流方式 5次等待排队
         */
        FlowRule flowRule2 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule2.setResource("限流等待-5");
        //限流阈值
        flowRule2.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule2.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule2.setControlBehavior(2);
        //超时时间设置
        flowRule2.setMaxQueueingTimeMs(60000);

        /**
         * 添加限流方式 2次拒绝访问
         */
        FlowRule flowRule3 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule3.setResource("限流-2");
        //限流阈值
        flowRule3.setCount(2);
        //调用关系限流策略:直接、链路、关联
        flowRule3.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule3.setControlBehavior(0);

        /**
         * 添加限流方式 10次等待排队
         */
        FlowRule flowRule4 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule4.setResource("限流等待-10");
        //限流阈值
        flowRule4.setCount(10);
        //调用关系限流策略:直接、链路、关联
        flowRule4.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule4.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule4.setControlBehavior(2);
        //超时时间设置
        flowRule4.setMaxQueueingTimeMs(60000);

        /**
         * 添加限流方式 线程最多五个
         */
        FlowRule flowRule5 = new FlowRule();
        //资源名,资源名是限流规则的作用对象
        flowRule5.setResource("线程-5");
        //限流阈值
        flowRule5.setCount(5);
        //调用关系限流策略:直接、链路、关联
        flowRule5.setStrategy(0);
        //限流阈值类型,QPS 或线程数模式
        flowRule5.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        //流控效果(直接拒绝 / 慢启动模式 / 排队等待),不支持按调用关系限流
        flowRule5.setControlBehavior(0);
        //超时时间设置
        flowRule5.setMaxQueueingTimeMs(60000);

        /**
         * 组装限流
         */
        flowRules.add(flowRule1);
        flowRules.add(flowRule2);
        flowRules.add(flowRule3);
        flowRules.add(flowRule4);
        flowRules.add(flowRule5);
        FlowRuleManager.loadRules(currentLimitRules(flowRules));
    }

    /**
     * 限流规则配置
     */
    protected abstract List<FlowRule> currentLimitRules(List<FlowRule> rules);

}
@Configuration
public class SentinelConfig extends CustomSentinelConfig {
    @Override
    protected List<FlowRule> currentLimitRules(List<FlowRule> rules) {
        return rules;
    }
}
@RestController
public class SentinelController {
    @SentinelResource(value = "线程-5",blockHandler = "blockHandlerTest")
    @RequestMapping(value = "/myTest")
    public String myTest(String id, HttpServletResponse response) throws Exception {
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "访问结果";
    }

    public String blockHandlerTest(String id, HttpServletResponse response, BlockException b) throws Exception {
        return "错误代码";
    }
}

 4、Sentinel的持久化

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

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

相关文章

HMAC算法详解

1.HMAC算法 1.1 HMAC算法简介 HMAC&#xff08;Hash-based Message Authentication Code&#xff0c;散列消息认证码&#xff09;是一种使用密码散列函数&#xff0c;同时结合一个加密密钥&#xff0c;通过特别计算方式之后产生的消息认证码&#xff08;MAC&#xff09;。它可…

Go语言使用中遇到的错误

Go语言使用中遇到的错误 1、go: go.mod file not found in current directory or any parent directory. 先运行这一行代码&#xff1a; go mod init name再运行你的 go get 命令就好了。 2、Failed to build the application: main.go:4:2: package generateproject/route…

C++之报错:is an inaccessible base of(一百四十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

物业管理变牛的好办法,新手零基础必备!

随着城市化进程的加速和商务发展的蓬勃&#xff0c;写字楼作为商业活动的核心场所&#xff0c;在现代都市生活中扮演着至关重要的角色。 随之而来的安全威胁和管理难题也日益凸显。因此&#xff0c;为了确保写字楼内部的安全与秩序&#xff0c;提高工作人员和访客的出入效率&am…

slab 内存池的设计与实现

目录 从一个简单的内存页开始聊 slab slab 的总体架构设计 slab 的组织架构 ​编辑 ​编辑 参考文献 伙伴系统内存分配原理的相关内容来看&#xff0c;伙伴系统管理物理内存的最小单位是物理内存页 page。也就是说&#xff0c;当我们向伙伴系统申请内存时&#xff0c;至少…

Windows:prometheus + grafana + wmi_exporter+ 主机信息监控页面 + 支持主机信息告警

1、PrometheusGrafana环境搭建 1.1、Prometheus 下载地址&#xff1a;Download | Prometheus 选择对应的系统的版本下载并解压压缩包&#xff0c;运行程序 本人在window系统上操作 双击 验证 浏览器输入http://localhost:9090/ 点击Staatus>Targets 出现以下即成功 1.…

Unifying Large Language Models and Knowledge Graphs: A Roadmap

5.2 LLM-augmented KG Completion 知识图谱补全(KGC)是指对给定知识图谱中缺失的事实进行推断的任务。与KGE类似,传统的KGC方法主要关注于KG的结构,而没有考虑广泛的文本信息。然而,最近llm的集成使KGC方法能够对文本进行编码或生成事实,以获得更好的KGC性能。这些方法根据…

【数据科学赛】2023大模型应用创新挑战赛 #¥10万 #百度

CompHub 主页增加了“近两周上新的奖金赛”&#xff0c;更加方便查找最新比赛&#xff0c;欢迎访问和反馈&#xff01; 以下内容摘自比赛主页&#xff08;点击文末阅读原文进入&#xff09; Part1赛题介绍 题目 2023大模型应用创新挑战赛 举办平台 Baidu AI Studio 主办方…

git介绍和使用

目录 一、git概述 1、简介 2、下载安装 二、git代码托管服务 1、常用的 Git 代码托管服务 2、使用码云代码托管服务 三、git常用命令 1、git全局设置 2、获取git仓库 3、工作区、暂存区、版本库 概念 4、Git工作区中文件的状态 5、本地仓库操作 6、远程仓库操作 …

Jetson Nano介绍

1. bo1公版介绍 Jetson NanoBO1公版的实物图如下图所示。其中1是TF卡接口&#xff0c;可以进行系统镜像烧写&#xff1b;2是40PIN GPIO扩展接口&#xff1b;3是用来传输数据或使用电源供电的Micro USB接口&#xff1b;4是千兆以太网口&#xff1b;5是USB3.0接口&#xff1b;6是…

CentOS Linux的替代品(五)_BigCloud Enterprise Linux for Euler 21.10 U 3基础安装教程

文章目录 CentOS Linux的替代品&#xff08;五&#xff09;_BigCloud Enterprise Linux for Euler 21.10 U 3基础安装教程一、BC-Linux简介二、BigCloud Enterprise Linux for Euler 21.10U3基础安装2.1 下载地址2.2 安装过程 三、简单使用3.1 关闭selinux3.1.1 临时关闭selinu…

QT学习笔记:QT的信号与槽

一、信号与槽&#xff08;Signal & Slot&#xff09;的基本概念 1、了解信号与槽 &#xff08;1&#xff09;信号&#xff08;Signal&#xff09;&#xff1a;在特定情况下被发射的事件&#xff0c;例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号&…

Pytest测试框架快速搭建

一、介绍 pytest是一个非常成熟的Python测试框架&#xff0c;能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08;pytestrequests&#xff09;&#xff1b;pytest具有很多第三方插件&#xff0c;并且可…

springboot整合腾讯企业邮箱/企业微信邮箱

springboot整合腾讯企业邮箱/企业微信邮箱 登录后点击“客户端设置” 2.勾选红框中选项并保存 3.点击微信绑定并绑定微信 4.绑定微信后点击生成新密码并保存(复制生成的密码后面会使用) 5.将配置复制到代码中 <dependency><groupId>com.sun

凤凰架构阅读记录-三(分布式算法)

1.Paxos 世界上只有一种共识协议&#xff0c;就是 Paxos&#xff0c;其他所有共识算法都是 Paxos 的退化版本。 算法流程: 1.提案节点&#xff1a;称为 Proposer&#xff0c;提出对某个值进行设置操作的节点&#xff0c;设置值这个行为就被称之为提案&#xff08;Proposal&a…

【海量数据挖掘/数据分析】 之 K-NN 分类(K-NN、K-NN实例、准确率评估方法、准确率、召回率)

【海量数据挖掘/数据分析】 之 K-NN 分类(K-NN、K-NN实例、准确率评估方法、准确率、召回率) 目录 【海量数据挖掘/数据分析】 之 K-NN 分类(K-NN、K-NN实例、准确率评估方法、准确率、召回率) 一、 K-NN 简介 二、K-NN 分类 三、K-NN 分类实例 1、1-NN 分类 : 此时 A 类别…

leetcode 859. Buddy Strings(同伴字符串)

给出字符串s 和 goal, 判断交换 s 中的一对字母是否能得到goal. 必须是不同位置字母的交换。 思路&#xff1a; 先考虑边界情况&#xff0c; s 和 goal 的长度不相等时&#xff0c;s 怎么交换都不会得到goal. s 的长度 < 2时&#xff0c;没有可交换对象&#xff0c;肯定是…

【力扣】94、二叉树的中序遍历

94、二叉树的中序遍历 注&#xff1a;二叉树的中序遍历&#xff1a;左根右&#xff1b; // 非递归&#xff1a; var inorderTraversal function (root) {const arr [];//创建新数组&#xff1b;const stack [];//创建一个栈道&#xff1b;let o root;while( stack.length |…

办公实现降本增效,可借助微服务开源平台的力量!

在如今的快节奏发展时代&#xff0c;低代码开发平台拥有了一个广阔的发展天地&#xff0c;逐渐在通信业、医疗、物流、高校等众多大中型企业中获得一个立足之地&#xff0c;是助力企业提质、降本、增效的得力助手。微服务开源平台可以让企业实现这一目的&#xff0c;那么对于企…

AMBER分子动力学能量优化与分析、结合自由能计算专题

AMBER分子动力学能量优化与分析、结合自由能计算专题 第一天 时间:AM9:00~9:50 内容:六.分子动力学入门理/论 教学目标&#xff1a;了解本方向内容、理论基础、研究意义。 主要知识点:4分子力学简介 4.1分子力学的基本假设 4.2分子力学的主要形式 5分子力场 5.1分子力场的简…