微服务系列:Spring Cloud Alibaba 之 Sentinel 高级流控规则

2023-11-17

在上一篇中,我们学习完了 Sentinel 的基本流控规则,这篇我们来研究一下 Sentinel 的高级流控规则。

话不多说,开始今天的学习。

一、概述

控制台打开流控规则的高级选项如下

image-20220128220831623

出现了 流控模式流控效果 配置选项,这些配置项都是什么意思呢?

  • 流控模式:

    • 直接:api 达到限流条件时,直接限流
    • 关联:当关联的资源达到限流阈值时,就限流自己
    • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到峰值,就进行限流)【api级别的针对来源】
  • 流控效果:

    • 快速失败:直接失败,抛异常
    • Warm Up:根据coldFactor(冷加载因子,默认3)的值,从阈值/coldFactor,经过预热时长,才达到设置的QPS阈值
    • 排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效

接下来,让我们详细研究一下。

二、流控模式

1. 直接

api 达到限流条件时,直接限流

这个没什么好说的,直接 + 快速失败是默认的流控模式,在微服务系列:Spring Cloud Alibaba 之 Sentinel 基本流控规则 这篇中,我们的案例就是使用的这种默认的流控模式。

2. 关联

当关联的资源达到限流阈值时,就限流自己

假设 testA 关联 testB,当与 A 关联的资源 B 达到阈值后,就限流 A 自己,比如支付接口达到阈值时,就去限流下订单接口

@RestController
public class TestController {

    @GetMapping("/testA")
    public String testA(){
        return "testA....";
    }

    @GetMapping("/testB")
    public Object testB(){
        return "testB......";
    }
}

我们在控制台中这样配置

image-20220128224207332

保存之后,我们浏览器访问地址 localhost:9201/testAlocalhost:9201/testB 发现都是正常返回,没有问题,此时我们就要借助工具来模拟了

这里我们使用 postman 来测试,原理是使用 postman 启动一个 runner 来不停的访问着 /testB 接口,使 /testB 资源处于达到阈值的状态,然后我们再浏览器访问 /testA ,就会触发 /testA 的限流,当 /testB 恢复到没有达到阈值的状态时,/testA 访问恢复正常,不再触发限流。

注意:这里 /testB 达到阈值,/testB 并不会请求失败,只是给 /testA 的一种状态

  • postman 中新增一个 collections ,加入一个访问 /testB 请求

image-20220128225130692

  • 点击 Run

image-20220128225311842

  • 设置循环 50 次,间隔时间是 1 毫秒

image-20220128225757841

/testA 触发限流

image-20220128230026953

等 postman 中的 /testB 执行完之后,/testA 接口恢复正常

image-20220128230131094

3. 链路

只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到峰值,就进行限流)

它的功能有点类似于针对来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。

直接看概念可能不太好理解,我们直接上案例:

3.1、两个接口同时调用资源 testC

@RestController
public class TestController {

    @Autowired
    private ITestServiceImpl testService;

    @GetMapping("/testA")
    public String testA(){
        return testService.testC();
    }

    @GetMapping("/testB")
    public Object testB(){
        return testService.testC();
    }
}

3.2、@SentinelResource 定义资源 testC

public interface ITestService {
    String testC();
}

@Service
public class ITestServiceImpl implements ITestService {

    @Override
    @SentinelResource(value = "testC", blockHandler = "testCBlockHandler")
    public String testC() {
        return "调用 testC 资源";
    }

    public String testCBlockHandler(BlockException ex)
    {
        return "testC 触发限流...........";
    }
}

3.3、配置文件:禁止收敛URL的入口 context

spring:
  cloud:
    sentinel:
      web-context-unify: false # 关闭 context 整合

说实话这里有个坑,低版本可能不生效

从1.6.3 版本开始,Sentinel Web filter 默认收敛所有URL的入口 context,因此链路限流不生效。

1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在 CommonFilter 引入了WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。

本篇文章使用的 SCA 是 2.2.5 版本,也就是可以直接用这个 web-context-unify: false 来使链路限流生效

<spring-cloud-alibabersion>2.2.5.RELEASE</spring-cloud-alibaba.version>

3.4、启动项目测试

启动项目,访问一下 localhost:9201/testA 地址,观察控制台

image-20220129135714552

树状视图下,可以看到资源 /testA 调用了资源 testC,此时我们给资源 testC 添加链路限流规则

image-20220129140000032

意思是,从入口资源 /testA 调用资源 testC 一旦超过阈值,则触发限流

我们来测试一下,浏览器快速刷新 localhost:9201/testA 地址,触发限流

image-20220129140218967

快速刷新 localhost:9201/testB ,不触发限流

image-20220129140357351

注:

虽然在树状视图下显示有两个 testC 资源,但其实是一个,切回列表视图看看

image-20220129140515196

image-20220129140603393

三、流控效果

1. 快速失败

快速失败是默认效果,即当触发限流时,立即抛出异常 FlowException,立即失败。

2. Warm Up

Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

设置阈值为 10 ,预热时间是 5 秒,逐渐增加到阈值上限,所以会有一个初始阈值

初始阈值 = 阈值上限 / coldFactor, coldFactor 是冷加载因子,默认为3

image-20220129143146039

上面这个配置的效果就是:在 5 秒内最大阈值是 3(10/codeFactor),超过5秒,最大阈值为10

浏览器快速刷新 localhost:9201/testA 地址,5 秒内会出现限流,5 秒之后阈值上升为 10

image-20220129144040336

注意:

是每次从流量进来时候都会开始"冷启动",也就是一波请求访问完之后,中间间隔了点时间,再来一波请求同样会重新开始冷启动

3. 排队等待

匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效

排队等待方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

注意:匀速排队模式暂时不支持 QPS > 1000 的场景。

image-20220129153245588

testA 接口打印日志

@GetMapping("/testA")
public String testA(){
    log.info(Thread.currentThread().getName() + "\t" + "testA......");
    return "testA....";
}

控制台设置排队等待规则

image-20220129153047874

当阈值设为 2 的时候,则代表一秒匀速的通过 2 个请求,也就是每个请求平均间隔恒定为 1000 / 2 = 500 ms,每一个请求的最长等待时间(maxQueueingTimeMs)为 1s 。

快速访问地址 localhost:9201/testA,观察控制台日志,每秒确实匀速通过两个请求

image-20220129153609969

但这个 超时时间 我不是很理解什么意思,网上看到的很多都是错的。

流量控制 匀速排队模式 · alibaba/Sentinel Wiki · GitHub

官网上是这么说的

固定的间隔时间让请求通过。当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值,则让当前请求通过;否则,计算当前请求的预期通过时间,如果该请求的预期通过时间小于规则预设的 timeout 时间,则该请求会等待直到预设时间到来通过(排队等待处理);若预期的通过时间超出最大排队时长,则直接拒接这个请求。

不知道有没有小伙伴不吝赐教下!

PS:都看到这里了,点个赞吧,彦祖

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微服务系列:Spring Cloud Alibaba 之 Sentinel 高级流控规则 的相关文章

  • Numpy章节 3 高级功能

    章节 3 高级功能 1 数组的迭代和排序 NumPy提供了迭代数组元素的方法 并且可以对数组进行排序 示例代码 arr np array 3 1 5 2 4 迭代数组元素 for x in arr print x 输出 3 1 5 2 4

随机推荐

  • matlab运行一直正忙,MATLAB运行时一直处于忙的状态,是不是程序存在死循环

    本帖最后由 安然娜124 于 2016 4 26 21 37 编辑 疑惑 1 该程序点击运行后一直处于忙的状态 好久都没反应 不知道是程序中for语句太多导致的 还是语句存在死循环 2 如果程序可以运行 不管出没出结果 是不是都代表所编的程
  • 使用JavaScript调用常用浏览器,解决IE浏览器兼容性问题

    目录 前言 JavaScript代码 此贴为个人学习记录 便于以后使用 前言 开发中经常会遇到用户使用IE浏览器的情况 但是由于各种兼容问题 网页实际显示效果和开发的效果有较大出入 所以有了以下解决方案 如果当前网页用户使用IE浏览器打开
  • Pytorch中经常见到的View( )函数

    Pytorch里经常会见到tensor view a b c a b c等等都是函数内的参数 可以理解为reshape功能 重构张量的维度 比如 a torch Tensor 2 3 print a tensor 0 0000 0 0000
  • 3D星球动画html,基于Three.js实现的3D土星(星球)动画

    JavaScript 语言 JaveScriptBabelCoffeeScript 确定 function getMat color our material is a phong material with no shininess hi
  • 【c++primer第五版】第六章函数-函数基础、参数传递、返回类型、函数重载、函数指针

    目录 函数基础 局部对象 函数声明 参数传递 main 处理命令行选项 特殊用途语言特性 调试帮助 函数匹配 函数指针 函数是一个命名了的代码块 通过调用相应的函数来执行相应的代码 函数可以有0或多个参数 通常会产生一个结果 也可以重载函数
  • QT——C++ 多线程05

    目录标题 一 创建多线程的方式 一 方式一 二 方式二 三 方式三 一 创建多线程的方式 QT创建 使用 多线程的方式有三种 直接创建QThread 对象 重写run方法 最后调用start方法启动线程 通过调用QObject类提供的mov
  • k8s基础概念、ETCD

    原理 和k8s结合点 etcd与k8s的交集 维护 基础概念 物理组件 逻辑组件 网络组件 工作负载 1 物理组件 Master Control plane kube apiserver 提供唯一api接口 提供集群管理接口 用户认证授权
  • 【Qt】使用 setWindowFlags 方法设置窗体的最小化、最大化、关闭按钮

    一 设置方法 void setWindowFlags Qt WindowFlags type Qt WindowFlags 有很多参数 其中 窗口最小化按钮 Qt WindowMinimizeButtonHint 窗口最大化按钮 Qt Wi
  • html 识别文本中的\n 进行换行

    文本内容有 n 怎么换行 1 v html渲染 使用正则将 n 替换成 br 标签 再用v html渲染 this content value replace n g br div div 2 使用css的white space div t
  • 学好少儿编程做人工智能开拓者

    乔布斯曾经说过 人人都应该学习编程 因为它教会你如何思考 格物斯坦小坦克认为少儿编程教育已经不再是一个遥远的话题 它逐渐成为一个趋势 成为一个现实 少儿教育编程行业领域的火爆 也反映出了国家对于少儿编程教育的重视 以及行业对编程人才的刚性需
  • 虚拟化技术7小问

    目录 kvm中的虚拟机cpu核心大于1 虚拟机就不能启动 只能设置为1的时候虚拟机才能启动 是什么原因 如何查看虚拟机宿主机的CPU是否支持硬件虚拟化 宿主机支持虚拟化 是不是还要开启相关的设置 虚拟机中再安装的虚拟机是不是只能是单核的虚拟
  • 存储器基础入门

    1 泰瑞达机台 Magnum VU本身作为一个灵活 集合式的测试平台 可以支持所有NAND以及MCP MCP Multiple Chip Package 存储器 MCP是在一个塑料封装外壳内 垂直堆叠大小不同的各类存储器或非存储器芯片 是一
  • Android TabLayout setupWithViewPager()方法绑定Viewpager不显示文字

    setupWithViewPager 做了什么事情 TabLayout tabLayout findViewById R id tabLayout ViewPager viewPager findViewById R id viewPage
  • spring框架---IOC

    spring框架的概述 spring是轻量级的开源的JavaEE框架 解决企业应用的开发复杂性 spring有两个核心 IOC AOP IOC 控制反转 把创建对象的过程交给Spring进行管理 AOP 面向切面 不修改源代码的进行功能增强
  • SpringBoot小知识点(可能有你不知道的)

    SpringBoot复习 基础部分 1 SpringBoot中配置文件使用 配置文件间的加载优先级 properties 最高 gt yml gt yaml 最低 2 yaml数据读取 对于yaml文件中的数据 其实你就可以想象成这就是一个
  • 【Salvation】——怪物角色动画&主角碰撞死亡动画

    Salvation 怪物角色动画 主角碰撞死亡动画 写在前面 这个动画功能同样也是使用JavaScript编写脚本 在Unity3D游戏引擎的环境中实现 在怪物的角色动画中 很多与人物相同 这里不再重复 一 设计敌人 拖一个精英sprite
  • Tcp通信步骤

    package cn dali4 code01 TCP通信步骤 服务器先启动 服务器端不会主动请求客户端 必须使用客户端请求服务器 客户端和服务器端建立一个逻辑连接 这个链接包含了一个IO对象 客户端和服务器端可以使用IO对象进行通信 IO
  • 树莓派软连接修改(python为例)

    树莓派软连接修改 进入linux的软连接存放位置 cd usr bin 删除原有软连接 以python为例 rm python 建立新软连接 以python连接python3为例 ln s usr python bin python3 us
  • 大数取模运算,快速幂取模运算

    1 快速幂取模 http www cnblogs com yinger archive 2011 06 08 2075043 html 快速幂取模就是在O logn 内求出a n mod b的值 算法的原理是ab mod c a mod c
  • 微服务系列:Spring Cloud Alibaba 之 Sentinel 高级流控规则

    微服务系列 Spring Cloud Alibaba 之 Sentinel 基本流控规则 在上一篇中 我们学习完了 Sentinel 的基本流控规则 这篇我们来研究一下 Sentinel 的高级流控规则 话不多说 开始今天的学习 一 概述