【微服务保护】Sentinel 流控规则 —— 深入探索 Sentinel 的流控模式、流控效果以及对热点参数进行限流

news2024/11/7 10:37:19

文章目录

  • 前言
  • 一、快速掌握 Sentinel 的使用
    • 1.1 什么是簇点链路
    • 1.2 Sentinel 的简单使用示例
  • 二、Sentinel 流控模式
    • 2.1 直接模式
    • 2.2 关联模式
    • 2.3 链路模式
  • 三、流控效果
    • 3.1 快速失败
    • 3.2 预热模式
    • 3.3 排队等待
  • 四、对热点参数的流控
    • 4.1 热点规则
    • 4.2 热点规则演示


前言

微服务架构的流行使得在分布式系统中保障稳定性变得尤为关键。在前文中,已经讨论了微服务中可能出现的雪崩问题以及相应的解决方案。作为确保系统可用性的关键工具之一,Sentinel 应运而生,它是一款功能强大的流量控制组件,为开发人员提供了多种方式来管理和保护微服务。

在本文中,我将深入探讨 Sentinel 的核心功能,包括流控模式、流控效果和对热点资源的限流策略。深入了解这些概念,并通过示例演示如何在 Spring Cloud 项目中使用 Sentinel,以便更好地应对各种流量控制和限流需求。

一、快速掌握 Sentinel 的使用

1.1 什么是簇点链路

在学习 Sentinel 的使用之前,我们有必要首先了解一下簇点链路。所谓的簇点链路就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下 Sentinel 会监控 Spring MVC 的每一个端点(Endpoint),因此 SpringMVC 的每一个端点(Endpoint)就是调用链路中的一个资源。

流控、熔断等都是针对簇点链路中的资源来设置的,因此我们可以点击对应资源后面的按钮来设置规则:

1.2 Sentinel 的简单使用示例

现在,我们需要对 /order/{orderId} 这个路径进行限流,要求它的 QPS 每秒不能超过 5,设置步骤如下:

  1. 在簇点链路中,在指定的链路下点击添加流控规则:

  1. 设置流控规则,QPS 不超过 5:


新增之后,可以在流控规则中查看这条新增的规则:

  1. 使用 Jmeter 进行测试
    设置线程属性:

设置了20个线程,线程的启动时间是 2s,此时的 QPS 是10。

配置 HTTP 请求:


在这个 HTTP 请求中,访问的资源是 /order/101

启动 JMeter 进行测试:

通过结果树可以发现,连续请求成功的请求数不会超过5。

二、Sentinel 流控模式

Sentinel 是一款功能强大的流量控制组件,它支持多种流控模式,以帮助开发人员更好地管理和保护微服务。下面将介绍 Sentinel 的三种主要流控模式:直接模式、关联模式和链路模式。

在使用 Sentinel 添加限流规则时,点击高级选项,可以选择三种流控模式:

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式;
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流;
  • 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流;

2.1 直接模式

直接模式是 Sentinel 最基本的流控模式,它通过对资源的访问频率进行限制来控制流量。在直接模式下,可以为每个资源配置允许的 QPS(每秒查询率)限制。如果某个资源的实际流量超过了配置的限制,Sentinel 将拒绝或降级该资源的访问请求。

这种模式适用于需要对某个具体资源进行流控的场景,例如 API 接口、微服务等。通过配置直接模式,您可以保护关键资源免受过多请求的干扰,确保系统的稳定性和可用性。

上文中 Sentinel 的简单使用示例就是直接模式,它是对order/{orderId} 这个具体的请求资源进行限流。

2.2 关联模式

关联模式是 Sentinel 提供的一种更为灵活的流控模式。在关联模式中,可以定义多个资源之间的关联关系,然后基于这些关联关系来控制流量。这使得可以更好地适应多资源之间的复杂交互。

简单来说,关联模式的作用是统计与当前资源相关的另一个资源,当触发资源访问的阈值时,对当前资源限流。

关联模式的使用场景:

比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是有限支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。

例如,下面在 order-service 中新增两个接口,query 表示查询订单,update 表示更新订单:

@GetMapping("/query")
public String queryOrder(){
    return "查询订单成功!";
}

@GetMapping("/update")
 public String updateOrder(){
     return "更新订单成功!";
 }

下面通过关联模式,设置对 query 接口的限流:

此时,将 queryupdate 两个接口进行关联,当 update 资源被访问的 QPS 超过 5 时,就会对 query 接口进行限流。

使用 JMeter 测试:

设置线程数,此时 QPS 为 10:

设置 HTTP 请求:

启动 JMeter 进行测试:

此时发送可以正常处理 update接口的请求,但是此时我们通过浏览器访问query 接口,发现该接口被 Sentinel 限流了:


这就是关联模式,通过上面的例子可以得出结论:

满足下面条件可以使用关联模式:

  • 两个有竞争关系的资源;
  • 一个优先级较高,一个优先级较低。

2.3 链路模式

链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。

例如有两条请求链路test1test2,从它们都可以服务到 commom 资源:

  • /test1 -> /common
  • /test2 -> /common

如果只希望统计从/test2进入到/common的请求,则可以使用链路模式进行配置:

现在有一个需求:有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流。设置的步骤如下:

  1. OrderService中添加一个queryGoods方法,不用实现业务:

    @SentinelResource("goods") // Sentinel 标记除 Controller 以外的方法
    public void queryGoods(){
        System.err.println("查询商品!");
    }
    

    注意,在默认情况下,Sentinel 只会监视 Controller 中的端点方法,如果要监视其他方法,可以使用 @SentinelResource 注解。

    另外,Sentinel 默认会将 Controller 方法做 context 整合,导致链路模式的流控失效,需要修改application.yml,添加如下配置:

    spring:
      cloud:
        sentinel:
          web-context-unify: false # 关闭 Context 上下文整合
    
  2. OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法:

    @GetMapping("/query")
    public String queryOrder(){
        // 查询商品
        orderService.queryGoods();
        // 查询订单
        System.out.println("查询订单");
        return "查询订单成功!";
    }
    
  3. OrderController中添加一个/order/save的端点,调用OrderServicequeryGoods方法:

    @GetMapping("/save")
    public String saveOrder(){
        // 查询商品
        orderService.queryGoods();
        // 新增订单
        System.out.println("新增订单");
        return "新增订单成功!";
    }
    
  4. queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS不能超过2:

  5. 使用 JMeter 进行测试
    设置线程,QPS 为 4:

    设置 HTTP 请求:


    分别设置了对 querysave 两个接口的 HTTP 请求。
    启动 JMeter:
    可以发现,对 query 接口进行限流了:

    而对 save 接口没有限流:

三、流控效果

在 Sentinel 中,流控效果是指当请求达到流控阈值时应该采取的措施。Sentinel 提供了多种流控效果,包括快速失败、预热模式以及排队等待。每种效果都适用于不同的使用场景,可以根据具体需求选择合适的流控效果。

  • 快速失败: 达到阈值后,新的请求会被立即拒绝并抛出 FlowException 异常。通过前文的演示,可以发现是默认的处理方式。
  • 预热模式: 对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
  • 排队等待: 让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长

这些模式可以在 Sentinel 控制台的高级选项中进行设置,下面分别是对这些流控效果的演示。

3.1 快速失败

快速失败 是 Sentinel 的默认流控效果。当请求达到流控阈值时,新的请求会被立即拒绝,并抛出 FlowException 异常。这意味着请求将立即失败,不会继续执行后续逻辑。这种效果适用于对系统资源有明确限制的场景,帮助尽早识别并拒绝过多请求,以避免系统超负荷运行。

使用快速失败效果可以保护系统免受过多请求的干扰,确保系统的稳定性和可用性。

3.2 预热模式

预热模式 也被称为 “warm up” 模式。在预热模式下,超出流控阈值的请求同样会被拒绝并抛出异常,但不同的是,流控阈值在一段时间内会逐渐增加到最大阈值。

预热模式是应对服务冷启动的一种方案。请求阈值初始值是 threshold / coldFactor,持续指定时长后,逐渐提高到threshold值。而coldFactor的默认值是3。

例如,设置QPS的threshold为10,预热时间为 5 秒,那么初始阈值就是 10 / 3 ,也就是 3,然后在 5 秒后从 3 逐渐增长到 10。


现在有一个需求:就是给/order/{orderId}这个资源设置限流,最大 QPS 为 10,利用 warm up 效果,预热时长为 5 秒,步骤如下:

1. 新增流控规则:


2. 使用 JMeter 进行测试:

设置 QPS 为10:
在这里插入图片描述
设置 HTTP 请求:

启动 JMeter ,查看 Sentinel 控制台实时监控:

可以发现,QPS 的值最近增大,拒绝的请求数量也逐渐减少。

3.3 排队等待

排队等待 流控效果允许所有的请求按照先后次序排队执行,保证请求之间的间隔不小于指定的时长。这意味着请求会进入队列等待处理,直到轮到请求执行。如果请求无法立即执行,它们将排队等待。

排队等待效果适用于需要有序执行请求的场景,例如需要按照请求的到达顺序处理的业务,或者要求请求间保持固定的时间间隔的场景。

例如:QPS = 5,意味着每 200ms 处理一个队列中的请求;timeout = 2000,意味着预期等待超过 2000ms 的请求会被拒绝并抛出异常。

现在有一个需求:给/order/{orderId}这个资源设置限流,最大 QPS 为10,利用排队的流控效果,超时时长设置为 5s,步骤如下:

1. 添加限流规则:

2. 使用 JMeter 进行测试:

设置 QPS 为 15:

设置 HTTP 请求:


启动 JMeter,查看 Sentinel 的实时监控:

可以发现,在排队等待流控模式下,请求会有序排队执行,这有助于削峰平谷。这种模式对于高并发场景和需要请求按照到达顺序处理的业务非常有用。通过将请求按照时间间隔排队执行,系统可以更好地应对流量的突发增加,降低系统的压力,从而提高系统的稳定性和可用性。

四、对热点参数的流控

4.1 热点规则

前文的限流都是统计访问某个资源的所有请求,判断是否超过 QPS 阈值。而热点参数限流是分别统计参数值相同的请求,判断是否超过QPS阈值。

例如下图所示,访问同样一个链路,但是这个链路中 id 为 1 的资源访问的次数比其他资源多,那么说明该资源是热点资源,就可以将该资源的 QPS 设置的大一些:

在 Sentinel 控制台中,可以发现有一个热点规则,通过这个规则就可以对热点资源进行流控设置,例如:


代表的含义是:对hot这个资源的 0 号参数(第一个参数)做统计,每 1 秒相同参数值的请求数不能超过 5。

另外,在热点参数限流的高级选项中,可以对部分参数设置例外配置:

结合上一个配置,这里的含义是对 0 号的 long 类型参数限流,每 1 秒相同参数的QPS不能超过 5,有两个例外:

  • 如果参数值是 100,则每 1 秒允许的QPS为 10;
  • 如果参数值是 101,则每 1 秒允许的QPS为 15。

4.2 热点规则演示

现在有一个需求,就是给 /order/{orderId} 这个资源添加热点参数限流,规则如下:

  • 默认的热点参数规则是每 1 秒请求量不超过 2;
  • 给 102 这个参数设置例外:每 1 秒请求量不超过 4;
  • 给 103 这个参数设置例外:每1秒请求量不超过 10;

1. 添加热点规则:

热点参数限流对默认的 SpringMVC 资源无效,因此需要使用 @SentinelResource() 注解指定热点资源名称:

2. 使用 JMeter 进行测试:

设置QPS 为 5:

设置 HTTP 请求:



这里分别设置了对 ID 为 101、102、103 三个不同资源的HTTP请求,对应了上述设置的规则的不同情况。

启动 JMeter:

对于 ID 为 101 资源的结果树,发现每秒只能通过 2 个请求:

对于 ID 为 102 资源的结果树,发现每秒只能通过 4 个请求:

对于 ID 为 103 资源的结果树,发现每秒 5 个请求都通过了:

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

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

相关文章

flutter doctor检测环境,出现CocoaPods installed but not working

1. 安装flutter, 地址: 安装和环境配置 - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 2. 安装成功后,通过flutter doctor检测环境。以mac为例,出现了CocoaPods installed but not working 错误提示时,以下为解决方案: 2.1 rvm i…

AJAX: 对话框大全

AJAX:$.ajax({url: "/admin/cutting/getDataWeek",type: "GET",data:{},dataType:json,success: function (res) {if (res.code 1) {}},error:function (error) {console.log(请求失败);console.log(error);}}); $(.sub).unbind(click).click(funct…

浅析云数据安全的必要性

随着企业和个人用户越来越多地将数据存储和处理移到云上,云数据安全变得至关重要。云计算的发展为我们提供了卓越的灵活性和可扩展性,但也伴随着潜在的风险。在这个信息高度互联的时代,保护敏感数据是一项迫切的任务。本文将探讨云数据安全的…

microcom串口调试工具使用

microcom串口助手使用介绍 microcom是一个在终端中使用的串口助手,类似平常使用SSCOM一样的东西,不过是在终端中使用而已。 使用的是busybox构建的文件系统 microcom源码路径:busybox/miscutils/microcom.c microcom 参数: [r…

QT计时器

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //计时器类 #include <QTime> //时间类 QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widg…

【视觉算法系列3】在自定义数据集上训练 YOLO NAS(下篇)

提示&#xff1a;免费获取本文涉及的完整代码与数据集&#xff0c;请添加微信peaeci122 YOLO-NAS是目前最新的YOLO目标检测模型&#xff0c;它在准确性方面击败了所有其他 YOLO 模型。与之前的 YOLO 模型相比&#xff0c;预训练的 YOLO-NAS 模型能够以更高的准确度检测更多目标…

C# Winform编程(7)文件处理技术

文件处理技术 System.IO命名空间File类的常用方法FileInfo类的常用方法文件夹类Directory的常用方法 System.IO命名空间 System.IO命名空间常用的类 类说明File提供用于创建&#xff0c;复制&#xff0c;删除&#xff0c;移动和打开文件的静态方法&#xff0c;并协助创建File…

python triangle库将一组闭合点转化为三角网格时网格过密的问题

输入点的格式&#xff1a; [[x1,y1], [x2,y2], … [xn,yn], ] segments 格式&#xff1a; 指示输入点的连接关系 三角化代码&#xff1a; t2 triangle.triangulate({vertices: path,segments: segments}, peq32.5a0.5)效果&#xff1a; 网格过密&#xff0c;根据文档&…

SystemVerilog Assertions应用指南 Chapter1.38在序列匹配时调用子程序

SVA可以在序列每次成功匹配时调用子程序。同一序列中定义的局部变量可以作为参数传给这些子程序。对于序列的每次匹配,子程序调用的执行与它们在序列定义中的顺序相同。 module sub;logic a, b, clk;initial $vcdpluson();initial begin clk 1b0; a1b0; b1b0; repeat(2) (pos…

代码随想录算法训练营第二十八天 | LeetCode 491. 递增子序列、46. 全排列、47. 全排列 II

代码随想录算法训练营第二十八天 | LeetCode 491. 递增子序列、46. 全排列、47. 全排列 II 文章链接&#xff1a;递增子序列 全排列 全排列II 视频链接&#xff1a;递增子序列 全排列 全排列II 目录 代码随想录算法训练营第二十八天 | LeetCode 4…

使用VGG框架实现从二分类到多分类

一.数据集的准备 与之前的不同&#xff0c;这一次我们不使用开源数据集&#xff0c;而是自己来制作数据集。重点需要解决的问题是对数据进行预处理&#xff0c;如每一个图片的大小均不同&#xff0c;需要进行resize&#xff0c;还需要对每一张图片打标签等操作。 数据集文件 …

根据pid查看jar包(windows)

打开jdk/bin/jvisualvm.exe,根据pid找到jar包的主启动类,jdk14以后不再默认使用,官网下载,也可以使用老版本的查看

虚拟机如何联网【NAT】

查看VMWARE的IP地址 #进入root用户 su -#更改虚拟网卡设置界面 vi /etc/sysconfig/network-scripts/ifcfg-ens33 修改ONBOOT为yes BOOTPROTO为static IPADDR为前面的网段 192.168.211.xx (xx为自己设置的&#xff0c;可以随意设置&#xff0c;前面的为前面查看的IP地址的前…

黑客技术(自学方法)——网络安全

前言 前几天发布了一篇 网络安全&#xff08;黑客&#xff09;自学 没想到收到了许多人的私信想要学习网安黑客技术&#xff01;却不知道从哪里开始学起&#xff01;怎么学&#xff1f;如何学&#xff1f; 今天给大家分享一下&#xff0c;很多人上来就说想学习黑客&#xff0c…

jupternotebook和jupterLab有什么区别?

目录 1.jupternotebook 2.jupterLab 3.总结 Jupyter Notebook和JupyterLab是两个常用的交互式计算环境&#xff0c;都是基于Jupyter项目开发的。它们具有一些共同的特性&#xff0c;但也存在一些区别。 1.jupternotebook Jupyter Notebook是Jupyter项目的早期版本&#xff…

【数据结构】线性表的顺序存储结构

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 一.顺序存储定义 上篇文章中介绍了线性表一共分为两种数据结构——顺序存储结构和链式存储结构. 今天我们就来一起学习一下第一种——顺序存储结构. 线性表的顺序存储结构,指…

AUTOSAR AP硬核知识点梳理(1)

一 什么是 Adaptive AUTOSAR? Adaptive AUTOSAR是一种新的汽车软件框架,旨在满足现代汽车行业中不断增长的技术需求。随着汽车变得越来越智能,对处理器的性能要求也在不断增长。 Adaptive AUTOSAR旨在通过提供高性能计算和通信机制以及灵活的软件配置来满足这些需求,为车…

代码随想录算法训练营第五十三天 | 309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 视频讲解&#xff1a; https://programmercarl.com/0309.%E6%9C%80%E4%BD%B3%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E6%97%B6%E6%9C%BA%E5%90%AB%E5%86%B7%E5%86%BB%E6%9C%9F.html &#xff08;1&#xff09;代码 714.买卖股票的最佳时机含手续费…

通过字符设备驱动并编写应用程序控制三盏灯亮灭

现象 键盘按1三灯全亮 按0三灯全灭 头文件.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014#defin…

底层驱动day2作业

控制三盏灯亮灭 代码&#xff1a; //head.h#ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_RCC 0x50000A28 #define PHY_GPIOE_MODER 0x50006000 #define PHY_GPIOF_MODER 0x50007000 #define PHY_GPIOE_ODR 0x50006014 #define PHY_GPIOF_ODR 0x50007014#endif //demo…