当前位置: 首页 > news >正文

七、手把手教你搭建SpringCloudAlibaba之Sentinel实现流量控制

 SpringCloud Alibaba全集文章目录:

零、手把手教你搭建SpringCloudAlibaba项目

一、手把手教你搭建SpringCloud Alibaba之生产者与消费者

二、手把手教你搭建SpringCloudAlibaba之Nacos服务注册中心

三、手把手教你搭建SpringCloudAlibaba之Nacos服务配置中心

四、手把手教你搭建SpringCloudAlibaba之Nacos服务集群配置

五、手把手教你搭建SpringCloudAlibaba之Nacos服务持久化配置

六、手把手教你搭建SpringCloudAlibaba之Sentinel实现流量实时监控

七、手把手教你搭建SpringCloudAlibaba之Sentinel实现流量控制

八、手把手教你搭建SpringCloudAlibaba之Sentinel服务降级

九、手把手教你搭建SpringCloudAlibaba之Sentinel热点key限流

十、手把手教你搭建SpringCloudAlibaba之Sentinel系统保护规则

十一、手把手教你搭建SpringCloudAlibaba之Sentinel服务熔断

十二、手把手教你搭建SpringCloudAlibaba之Sentinel规则持久化

十三、手把手教你搭建SpringCloudAlibaba之Seata分布式事务

点击跳转学习 -------------->手把手教你搭建SpringCloud项目

流量控制就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。

我们访问的接口http://localhost:8401/testA和http://localhost:8401/testB,在sentinel的控制台就可以看到的簇点链路菜单,如下所示。
 

 我们点击接口testA接口的流控按钮,可以看到如下的界面:

1、流量控制的几种模式

资源名

唯一名称,默认是请求路径,可自定义,Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解。

针对来源

指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制

阈值类型/单机阈值

QPS(每秒请求数量):

当调用该接口的QPS达到阈值的时候,进行限流

线程数:

当调用该接口的线程数达到阈值的时候,进行限流

是否集群:

暂不需要集群

流控模式

直接(默认)

接口达到限流条件时,开启限流

关联

当关联的资源达到限流条件时,开启限流

链路

当从某个接口过来的资源达到限流条件时,开启限流

流控效果

快速失败(默认):

直接失败,抛出异常,不做任何额外的处理,是最简单的效果

Warm Up:

它从开始阈值到最大QPS阈值会有一个缓冲阶段,一开始的阈值是最大QPS阈值的 1/3,然后慢慢增长,直到最大阈值,适用于将突然增大的流量转换为缓步增长的场景。

排队等待:

让请求以均匀的速度通过,单机阈值为每秒通过数量,其余的排队等待; 它还会让设 置一个超时时间,当请求超过超时间时间还未处理,则会被丢弃

2、直接模式

我们先演示流控模式为直接的,也是默认的模式。可以看到阈值的类型分为QPS和线程数两种,我们先设置一下QPS类型的,单机阈值直接填写1。新增完毕后我们就可以看到控制台流量规则的菜单里看到我们新增的那条流控规则,如下图:

我们访问接口testA接口,当前的QPS为1,每秒访问1次。如果每秒访问的次数超过1次,则会被Sentinel限流。看下我们刚刚设置的是否会成功。可以看到成功限流了。

那接下来我们设置下阈值的类型分为线程数的这种类型,单机阈值为1,就是每秒需要只允许一个线程访问,否则则会被Sentinel限流。看下我们刚刚设置的是否会成功。

 这个可以用Jmeter软件来协助我们测试。

3、关联模式

我们把之前配置的流控规则都删掉,我们重新配置关联流控模式testA接口关联testB接口,流控效果为快速失败,意思就是当我们指定的testA接口关联的testB接口达到限流条件时,开启对指定接口testA开启限流(就是B惹事,A来处理)。

我们狂点testB接口,超过每秒1次,然后接着访问testA接口,可以看到已经限流了,如下图:

4、链路模式

根据调用链路入口限流。是对链路之间树结构进行流控,各个资源之间进行相互调用,这些资源通过调用关系,相互之间构成一颗树。这课树的根节点是一个名为getUser的虚拟节点,调用链路的入口都是这个虚节点的子子节点。如下图:

 上图中来自入口的testA和testB的请求都调用了资源getUser,Sentinel允许只根据某个入口的统计信息对资源进行限流。

不但可以对接口进行流控,还可以对业务方法进行限流。我们新建getUser的方法,如下图:

@Service
public class UserServiceImpl implements UserService {
    @Override
    @SentinelResource(value = "getUserName")
    public String getUserName() {
        return "一直tom猫";
    }
}

分别将接口testA和testB接口调用getUser方法,代码如下:

@RestController
public class FlowLimitController {
    @Autowired
    private UserService userService;
    @GetMapping("/testA")
    public String testA() {

        return userService.getUserName();
    }

    @GetMapping("/testB")
    public String testB() {

        return userService.getUserName();
    }
}

重新方法接口testA和testB接口,可以看到业务方法getUser也注入到了sentinel当中,如下图:

 可以看到我们的资源getUserName,我们针对进行链路限流,入口资源我们限制testA,如下图。

我们的链路模式就建好了,记得把之前限流配置删掉,如下图:

我们访问testA接口发现不生效,并没有限流,如下图:

这是为什么呢?

因为我们sentinel的版本较高,直接使用链路模式是不生效的,那该如何解决呢?

 

我们需要在pom.xml中增加sentinel-web-servlet的依赖,如下图:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-web-servlet</artifactId>
</dependency>

在项目中添加一个FilterContextConfig配置类,代码如下:

@Configuration
public class FilterContextConfig {
    @Bean
    public FilterRegistrationBean sentinelFilterRegistration() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new CommonFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY,"false");
        registrationBean.setName("sentinelFilter");
        registrationBean.setOrder(1);
        return  registrationBean;
    }
}

重启项目,我们再次访问testA和testB接口,在看seninel的控制台,如下图:

可以发现现在的控制台的接口层级关系和之前不成功的时候层级关系是不一样的,可以看到现在可以看到正确的链路。接下来对testA接口中的getUser方法进行限流,配置如下:

访问接口testA,每秒没疯狂点击会出现如下的错误;

 访问接口testB,每秒没疯狂点击可以正确访问,如下图:

 出现如上的错误是因为我们使用了@SentinelResource,注解,使用了该注解就不会使用我们设置的全局的使用统一的异常错误处理里,就需要@SentinelResource注解当中的blockHandler参数进行单独的处理,需要写一个流控处理的方法,代码如下:

@Service
public class UserServiceImpl implements UserService {
    @Override
    @SentinelResource(value = "getUserName",blockHandler = "blockHandlerGetUser")
    public String getUserName() {
        return "一直tom猫";
    }

    public String blockHandlerGetUser() {
        return "请稍后再试";
    }
}

重启项目,再次访问testA接口,会出现我们自定义的处理限流的方法,如下图:

5、流控效果

流控效果一共分为三种:

直接失败:

是默认的流量控制模式,当QPS超过任意规则的阈值后,新请求就会被立即拒绝,拒绝的方式是抛出FlowException。这种方式适用于读系统处理能力确切已知的情况下,比如通压测确定了系统的准确水位时。其源码为:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController

Warm Up(预热)

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

冷加载因子:codeFactor默认3,即请求PQS从threshold/3开始,经预热时长逐渐升至设定QPS阈值。

我们以接口testA来演示一下预热模式,我们的阈值设置为10,预热时长为5,根据冷加载因子计算,系统的初始化的阈值为10/3约等于3,即阈值刚开始为3,然后通过5秒后阈值才慢慢升高恢复到10。

适用场景:电商系统中的秒杀活动,在秒杀系统的开始的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。

排队等待

匀速排队方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,阈值类型必须设置为QPS,否则无效。对应的是漏铜算法。

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

我们以接口testB来演示一下排队等待模式,QPS的阈值设置为1,超时时间为20000毫秒,我们进行访问可以看到每秒通过一次请求,也不会把系统压垮。如下图:

 至此sentinel流量控制就学完了。

相关文章:

  • vue3 创建vue3模板
  • js 导出 excel
  • Mybatis-Plus(核心功能篇 ==> 代码生成器(新版)
  • Intel汇编-LOOP循环检查ECX含零值
  • DBNet学习笔记
  • 1、搭建环境
  • 基于Java+Spring+vue+element社区疫情服务平台设计和实现
  • 【Leetcode】剑指Offer 34:二叉树中和为某一值的路径
  • CockroachDB架构-复制层
  • Netty 入门学习(1)
  • Android手部检测和手势识别(含训练代码+Android源码+手势识别数据集)
  • 【NLP】第4章 从头开始预训练 RoBERTa 模型
  • 第3章 循环神经网络
  • 机器学习入门八
  • java毕业设计流浪动物救助公益平台源码+lw文档+mybatis+系统+mysql数据库+调试
  • ➹使用webpack配置多页面应用(MPA)
  • Android系统模拟器绘制实现概述
  • Angular4 模板式表单用法以及验证
  • input的行数自动增减
  • JavaScript 一些 DOM 的知识点
  • Laravel 菜鸟晋级之路
  • PHP那些事儿
  • ucore操作系统实验笔记 - 重新理解中断
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 区块链将重新定义世界
  • 如何编写一个可升级的智能合约
  • 如何进阶一名有竞争力的程序员?
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 一个SAP顾问在美国的这些年
  • ​渐进式Web应用PWA的未来
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • (12)Linux 常见的三种进程状态
  • (173)FPGA约束:单周期时序分析或默认时序分析
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (ros//EnvironmentVariables)ros环境变量
  • (第二周)效能测试
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (论文阅读40-45)图像描述1
  • (十六)串口UART
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET6 命令行启动及发布单个Exe文件
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .net中我喜欢的两种验证码
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [100天算法】-二叉树剪枝(day 48)
  • [8-23]知识梳理:文件系统、Bash基础特性、目录管理、文件管理、文本查看编辑处理...
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)
  • [BSGS算法]纯水斐波那契数列