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

微服务保护 -- 初识 Sentinel(雪崩问题,快速入门Sentinel)

大家好,今天我们要来学习阿里巴巴开源的流量控制和熔断降级框架 – Sentinel 。

1、雪崩问题及解决方案

首选我们来了解一下雪崩问题及其解决方案,我们学习这个微服务保护,其实就是为了去应对类似于雪崩问题这样的服务故障。

1.1 什么是雪崩问题?

那什么是雪崩问题呢?我们来看一下这个场景。

image-20230206151805010

上面是我们微服务里面的部分服务,我们知道微服务里面的业务往会比较复杂,一个业务它可能会依赖多个其他的微服务。

比如,在我们的服务 A 中,有这样的一个业务,它依赖于服务B。

image-20230206152030612

而服务A 里面可能又有可能其他的业务,比如说它依赖于服务D。

image-20230206152211277

那现在假设说,服务D出现了故障!image-20230206152241457

那么我们在服务A内部依赖于服务D的这个业务请求,还能正常访问吗?

显然是不可能的,因为它访问这个服务D就必然要等待服务D的结果,那因为服务D出现了故障,那必然不能返回结果,结果就是它会阻塞在这里。

那这就导致了服务A内部的这个业务是不是也会阻塞在这里?阻塞就会导致它不会释放服务器的连接。

当然了,这个时候,服务A内部依赖的于服务b或c的业务还不受影响,但是你想想看,有第一个依赖服务D这样的业务请求,那也会有第二个和第三个。

假以时日,服务A内部依赖于服务D的这样的业务请求越来越多,而它们都不会释放连接,那后面是不是一定会把服务A所有的连接给占用了?

image-20230206153109233

那最后的结果就是tomcat资源耗尽,因为tomcat 资源是有限的嘛,此时再有新的请求进来,哪怕我不是访问服务D的,我依赖服务D的,我是不是也进不来了?

那这下是不是可以认为服务A也出现故障?

image-20230206153333120

那这不就是因为一个服务导致了什么?

导致了依赖于它的服务也出现了故障。那我们就要知道,在微服务里,这种调用关系可不止这么简单,而且会非常复杂!

image-20230206153527861

那如果因为服务A因为服务D被拖垮了,那肯定也会有其他的服务也依赖于服务D,最终是不是也会拖垮?

假如说再有其他服务它们依赖于服务A,那么这些依赖于服务A的这些业务是不是也会拖垮?

image-20230206153811353

到最后出现故障的服务越来越多,那么整个微服务群都不可用了,这不就是雪崩了吗?

所以什么是雪崩问题?

微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。

这个非常恐怖的呀,所以,在微服务里边,雪崩问题是一个必须要解决的问题!

那么用什么来解决呢?

1.2 雪崩问题解决方案

解决雪崩问题的常见方案有四种:

1.2.1 超时处理

设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待。

image-20230206154600501

比方说,现在有服务B和服务C,还有服务A,服务A中有一些业务依赖于服务B,还有一些业务依赖于服务C。

image-20230206154848632

随着服务C出现故障,服务A内部依赖于服务C的所有业务都会阻塞,日积月累,服务A也就故障了。

那么超时处理会这么办呢?它会在调用业务时加上一个超时的时间。例如一秒。

image-20230206155045703

也就是说当服务A它的业务,依赖于服务C时,它最多等一秒。如果服务C故障以后,这个等待超过了一秒

,不好意思,它会立即结束这个请求,不再返回给用户一个提示信息。

就跟你说,不好意思,请求失败了。那这个请求是不是就释放了,就不会导致一直占用Tomcat资源,是不是一定程度上缓解这个雪崩问题?

但为什么是缓解雪崩问题?而不是100%解决了雪崩问题?

我们想想,它只是等待了一秒以后把资源释放,那也就是说,最长等待时间是不是一秒?我们可以理解成一秒钟释放一个,那如果你释放请求的速度是一秒释放一个。

但现在假设说新的请求速度是每秒钟两个,你释放的速度没有进入的速度快,是不是终有一天服务A的资源也有可能会被耗尽?所以你设置超时时间也只是起到了一个缓解作用,并没有从根本上解决这个问题。

1.2.2 舱壁模式

限定每个业务使用的线程数,避免耗尽整个Tomcat的资源,因此也叫线程隔离。

舱壁模式是来自于我们现实生活中,船舱的一个设计。

image-20230206160601528

一些大型的轮船,它都会把船体利用这种隔板分割成独立的小的空间,隔板就相当于舱壁。

那么因为这些空间之间相互是隔离的,现在假设说,船体的某个部位撞上了冰山,漏水了,最多也是吧这个部分船舱给它填满水。

因为是隔离的,所以其他的船舱是不收影响的,那这样这个船是不是还可以承受啊,它可以承受一定的船舱进水嘛,其实也就提高了我们整整艘船的一个容灾能力。

那么这种模式延续到我们程序设计里面,它是怎么来做的呢?

image-20230206161629622

还是刚刚的案例,服务A可以看成整艘船,然而我们该怎么避免整个Tomcat挂掉呢?

我们就把Tomcat里面的资源,也就是线程,划分成一个一个的独立的线程池。image-20230206162049499

比方说给业务1分配10个线程池,业务2分配10个。

那么现在业务1进来之后,它依赖于服务B。

image-20230206162156606

那它最多使用10个线程,访问业务2,它依赖于服务C。

image-20230206162314892

它也最多使用10个线程。

那现在服务C出现故障了,那这个业务就会阻塞,占用我们的线程,但是,它最多占用10个。

那这个时候它能够使用的Tomcat 资源是不是有限呢?是不是就把这个故障隔离到了10个线程内了?

对此这个模式也叫线程隔离模式,它其实啊就避免了整个Tomcat资源耗尽的这种情况。

当然这个模式它确实解决了超时处理方案所遗留的问题,只不过资源可能会有一些浪费。

比如说,服务C宕机挂了,接下来你还是会尝试区请求这个服务C,明知道它已经挂掉了,你还要尝试访问,还要暂用我10个线程,是不是一种浪费?

1.2.3 熔断降级

由断路器统计业务执行的异常比例,如果超出阈值会熔断该业务,拦截访问该业务的一切请求。

这种模式,它里面会有一个断路器,断路器它可以去统计业务执行的异常比例。

也就是说,你这个业务里面,出现故障的请求和正常的请求之间的一个比例是什么样子的?如果超出了阈值,则会熔断这个业务,什么是熔断,就是拦截访问该业务的一切请求。

image-20230206170958243

我们还是用图来表示一下,这也是我们之前说的,出现雪崩的一个情况,就是服务A里面所有的业务度卡在这里了,然后把资源耗尽。

那熔断怎么去解决这个问题呢?

image-20230206171301335

它会去统计服务A里面的业务,比方说再服务A里面有一个业务是来访问服务D的,然后第一次是正常的,

结果后面两次都出现了故障,那这个时候我们的断路器就会统计了你这个异常比例,这一看,三个请求,两个故障,是不是异常比列达到了60%?

那假设说我们的阈值是50%,那是不是超出了阈值,那么这个时候就会出现熔断。image-20230206171541212

一旦出现熔断,那么再服务A内部还想访问服务D这个业务,也就是依赖于服务D的这个业务就无法再去访问服务D了。

只要是看到你是请求服务D的,就跟说:“滚!”,资源快速释放,那怎么可能会把它们耗尽呢?这不就解决了资源耗尽问题,而且既然知道立刻服务D是故障的,我压根不让你去访问它,是不是就不存在这种资源浪费的情况了?

1.2.4 流量控制

限制业务访问的QPS,避免服务因流量的突增而故障。

什么意思呢?比如说,这里有一个受保护的服务,它能承受的最大QPS是2,也就是每秒钟最多处理两个请求,但是现在有无数的请求涌过来,那你说他能承受得了吗?那肯定是不行的呀,这不被打成筛子了。

而一旦这个服务出现了故障,那依赖于这个服务的其他服务是不是也都跟着会出现故障,那岂不是也会出现雪崩状况,所以,我们一定要尽可能的避免服务因为流量过高而引起故障。

那我们该怎么办呢?这就用到了我们的 Sentinel 了。

image-20230206180418742

现在呢,假如真的有无数个请求融入过来,而Sentinel,它可以按照这个服务所能够承受的一个频率去释放请求,这个时候我们的微服务不久能从容应对这些请求了吗?

image-20230206183222410

那就避免了它出现故障,如果它不出现故障,那就不会把故障进行传递了,就不会出现雪崩问题了。

所以你看是不是把雪崩问题扼杀在了摇篮当中。因此流量控制,是预防雪崩控制。

2、服务保护技术对比

好的,各位,在上面,我们已经学习了雪崩问题以及常见的解决方案,而要实现这些解决方案,最好的方式肯定是使用现有的框架。

所以现在我们就要去对比一下实现服务保护的常见框架及其差别,这里呢,我们主要是对比一下Sentinel 和 Hystrix。

因为Hystrix是Spring Cloud 刚刚流行的这几年,推荐大家使用的。它是由Netflix 公司出品的,只不过随着Netflix公司宣布停止对Hystrix的升级和维护,现在就逐渐没落了。

人们也在尝试去寻找一个新的方案,而在这个时候,阿里巴巴就开源了一个项目,叫Sentinel, 并且已经成为SpringCloudAlibaba 当中的一个服务保护组件,现在已经被广泛的应用在国内的互联网公司。

image-20230207102337924

看上面的表格,我们主要关注红色的部分即可。

2.1 隔离策略

Sentinel 和 Hystrix 都支持 信号量来隔离,而Hystrix还支持线程池隔离,但默认情况下都是用线程池来隔离的。

这两种隔离有什么差别呢?

线程池大家可能会比较熟悉一点,因为我们说雪崩问题解决方案,舱壁模式举的就是线程池隔离的例子。

我们讲了,在一个业务请求进入TomCat以后,它会给每一个被隔离的业务创建一个独立的 线程池,每有一个被隔离的业务都会有一个独立的线程池,那自然也会有独立线程。

因此,它会比TomCat直接处理的这种方式会多出很多很多线程,那么可以认为线程池数量会成倍增长,那这种方式虽然隔离性比较好,但是随着线程数量增长,我们知道CPU它会带来一些额外的一个 上下文切换的消耗,所以整个服务的性能是会有一定的损失的。

而信号量隔离采用了的方案是什么呢?

当业务请求进入 TomCat 以后,我不会给你创建独立的线程池,而是去做一个统计,统计当前业务已经使用多少个线程了,然后我给你限制一下,说你只能使用10个,当你已经使用10个线程以后,再有新的业务需要去获取线程时,我就会阻止你了。

也就是说,它会限制每个业务能使用的线程数量,池子也就是那一个池子,TomCat默认的线程池,不去创建新线程,也不创建新的线程池。

这样就减少了线程的创建,在隔离的基础上并没有影响性能。但是,它这样的隔离性相比于线程池来讲会差一点,因为它毕竟是在同一个池子里面,只不过现在一个大锅饭,每个人拿个碗单独盛了。

这是两种隔离方式的差别。

2.2 熔断降级

熔断降级其实就是其实就是统计异常的比例,然后触发了异常比例的阈值,我就给你熔断,只不过在Sentinel里它可以除了统计异常请求的比例,它还可以统计慢调用的比例。

何为慢调用?

就是一个业务,它大多数情况下耗时都比较久,那它这个业务可能就会有问题,可能会拖慢我整个服务,有可能把我拖垮了,所以我可以把它熔断了。

但是在Hystrix 里默认都是基于这种异常的方式进行熔断降级的,所以Sentinel里面的这种熔断策略会更丰富一些。

2.3 限流

限流就是我们讲的流量控制,在Sentinel里,它支持基于QPS,还有调用关系的这种限流,甚至还可以针对热点的参数去做限流。这限流的方式多种多样。

而Hystrix里面,它没有专门的一个限流的控制,它其实就是基于这个线程池的,你的线程池设置成10,那你最多不就是10了嘛,是基于这种方式来限流的。所以这种限流的能力相对比较弱一点。

2.4 流量整形

流量整形就是让突发流量变成稳定的匀速的流量。那怎么做到的呢?

它可以支持慢启动,也就是预热模式,还有匀速排队等等。

所以这种方式让波动的请求变成匀速的请求,那我微服务处理起来就会更加的轻松。

在Hystrix里是不支持这样的功能的。

2.5 控制台

控制台就是我们所谓的UI界面,给你弄一个可视化的界面,方便你去查看操作。

在Sentinel 里,它有开箱即用的控制台,在里面你不仅仅可以去监控微服务,查看微服务运行状态,还可以去配置我们的降级规则,配完就立即动态生效了。

而在Hystrix 里,它的控制台只支持服务状态的功能,不具备动态修改规则这样的功能。

3、认识Sentinel 和 安装

接下来我们就去认识一下Sentinel 并且去安装一下它的控制台。

3.1.初识Sentinel

首先,我们都知道Sentinel是阿里巴巴开源的一款微服务流量控制组件。

官网地址:https://sentinelguard.io/zh-cn/index.html

image-20230215113756822

然后下面就是介绍了Sentinel 的一些特征:

​ •丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。

​ •完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。

​ •广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。

​ •完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

3.2 安装Sentinel

1、下载

sentinel官方提供了UI控制台,方便我们对系统做限流设置。大家可以在[Releases · alibaba/Sentinel (github.com)](https://github.com/alibaba/Sentinel/releases)下载。

image-20230215114505133

2、运行

将jar包放到任意非中文目录,打开终端执行命令:

image-20230215114823457

java -jar sentinel-dashboard-1.8.6.jar

如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:

配置项默认值说明
server.port8080服务端口
sentinel.dashboard.auth.usernamesentinel默认用户名
sentinel.dashboard.auth.passwordsentinel默认密码

例如,修改端口:

java -Dserver.port=8090 -jar sentinel-dashboard-1.8.6.jar

3.3 访问

访问http://localhost:8080页面,就可以看到sentinel的控制台了:账号密码都是 sentinel

image-20230217152351557

4、微服务整合Sentinel

要使用Sentinel肯定要结合微服务,这里我们使用以前用过的SpringCloud工程。有需要的小伙伴可以下载这个工程

springCloud案例演示: springcloud学习演示 (gitee.com)

项目结构如下:

image-20230217155001204

然后大家记得启动一下Nacos

image-20230217161211340

然后启动这三个项目:

image-20230217164625461

现在我们的微服务已经准备好了,那下一步就可以去整合Sentinel了。

我们基于order-service去讲解。

4.1 引入依赖

<!--sentinel-->
<dependency><groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

4.2 配置控制台

修改application.yaml文件,添加下面内容:

image-20230217165817510

弄完之后重启服务!!!

4.3 访问order-service的任意端点(接口)

打开浏览器,访问http://localhost:8088/order/101,这样才能触发sentinel的监控。

然后再访问sentinel的控制台,查看效果:

image-20230217170038899

5、限流规则

接下来我们就要去学习Sentinel的用法,去解决我们之前说到的雪崩问题。

之前我们在讲解雪崩问题的时候提到了4种解决方案,而Sentinel主要是实现了其中的三种。

分别是:

  1. 限流
  2. 线程隔离
  3. 降级熔断

5.1 快速入门

首先我们通过一个快速入门了解一下Sentinel它的限流基本用法。

我们先来了解一个概念。

簇点链路:

​ 当请求进入微服务时,首先会访问DispatcherServlet,然后进入Controller、Service、Mapper,这样的一个调用链就叫做簇点链路。簇点链路中被监控的每一个接口就是一个资源

​ 默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint,也就是controller中的方法),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源。

例如,我们刚才访问的order-service中的OrderController中的端点:/order/{orderId}

image-20230217171312093

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

  • 流控:流量控制
  • 降级:降级熔断
  • 热点:热点参数限流,是限流的一种
  • 授权:请求的权限控制

那也就是说,我们将来可以去给资源去做降级等等各种各样的操作。

那具体怎么去做呢?

比如,我们点击资源/order/{orderId}后面的流控按钮,就可以弹出表单。

image-20230217171558742

这个表单有几个需要你去填写的东西。

第一是资源名称,因为你点的是 /order/{orderId} 这个资源,所以默认资源名称就是它,也就说这个流控规则是针对这个请求的。

第二个是针对来源,就是说从哪访问过来的请求需要被限流,default 就是一切进来的请求都要被限流,那一般情况下限流我们不需要去制定来源,就是所有请求都要限流。

第三个是阈值类型,一般都选择QPS, QPS就是指并发量嘛,也就是说每秒钟的请求数量,而后面指定的单击阈值就是指这个QPS的上限。1就代表即每秒只允许1次请求,超出的请求会被拦截并报错。至于将来这个单击阈值设置多少呢?就设置你的这个接口它最大的一个并发量就行了。怎么知道自己的这个服务的并发量是多少呢?做压力测试。

5.1.1演示

接下来我们给 /order/{orderId}这个资源设置流控规则,QPS不能超过 5,然后利用Jemeter进行压力测试。

image-20230220113421407

使用Jemeter。

image-20230220115344481

我们可以看到,请求发出了,但是每次通过只有五个,另外的就失败了。

我们还可以看看Sentinel控制台。

image-20230220115632355

5.2 流控模式

通过快速入门,我们已经学习Sentinel 的基本用法,我们接下来就来看一下限流里面的高级配置。

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

image-20230220144633433

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流,也就是说 ,我现在有A和B两个资源,a触发了阈值,但我却对B做限流。
  • 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流,不是对当前资源做限流;例如,现在我有A,B,C三个资源,A和B都要访问资源C,但是我在统计资源C的时候,只统计从A过来的请求,B的我不管。

直接模式我们就不做过多介绍,我们主要来看关联模式和链路模式,它们在什么情况下选择去用呢?

5.2.1 关联模式

使用场景:我们有一个用户支付的业务,用户支付完了,要修改订单状态,同时,另外一边可能还会有用户要去查询订单,那大家都知道,查询和修改的动作,他们会去争抢数据库的锁,那因此会产生竞争关系。写的操作过于频繁,自然会影响读的操作,反之亦然。

但是我们知道在业务里面,支付业务更新订单,这个业务肯定优先级更高,我们肯定要用户优先支付呀,那查询业优先级相对较低,所以我们希望当更新订单的这个业务触发阈值时,说明它有更高的要求,那我们就要对查询业务做限流,防止它影响到我们的修改业务。

案例:

接下来我们通过一个案例来演示一下关联模式如何使用。

我们先在代码中增加两个接口。

image-20230220150458021

重启服务,查看sentinel控制台的簇点链路:

image-20230220150946774

重启之后,所有东西都消失了,我们得重新访问一下接口。

localhost:8082/order/query

localhost:8082/order/update

image-20230220151124405

现在我们得query 和 update 已经出现在Sentinel 控制台中了,现在我们的需求是,当update的QPS 达到 5时,对Query 做限流处理。

请问,我要给谁添加流控规则?

我们要记住,给谁限流我们就要给谁添加规则。

那我们就要给query 增加流控规则。

image-20230220152214404

我们接下来就使用Jmeter 去做一下测试。

image-20230220152949100

Jmeter 正常请求没有没有限流,我们看看query。

image-20230220153141146

确实被限流了。

总结一下:

满足以下两个条件我们可以使用关联模式。

  1. 两个有竞争关系的资源
  2. 一个优先级较高,一个优先级较低

5.2.2 链路模式

接下里我们来了解链路模式。这里我们直接通过一个例子来学习

例如我有两条请求链路:

  • /test1 --> /common

  • /test2 --> /common

一个是从test1 来访问 common,一个是test2访问common。、

而我们下面有这么一个配置。

image-20230220155606813

配置的资源名称是common,而流控的方式呢?是链路方式。入口资源是test2。

那入口资源这个配置的意思是什么呢?

就是我在做限流统计时,只统计从test2进入common的请求,那test1进来的我就不管了。

所以这种统计是对请求来源的一种统计。

问题来了,什么情况下?我们要用到这种模式呢?

​ 我有一个查询订单和创建订单的业务,而这俩业务都需要查询商品。那这不就形成了两个链路了吗?

从查询订单到查商品和创建订单到查商品。而我们知道查询订单业务的并发往往会比较高,但是查询商品这个业务肯定会有自己的并发上限,如果查询业务的并发过高,势必会影响到创建订单的业务,那因此,我们应该把查询业务的并发做一个限制,怎么做呢?

步骤:

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

  2. 在OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法

  3. 在OrderController中添加一个/order/save的端点,调用OrderService的queryGoods方法

  4. 给queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS必须小于2

知道了步骤,我们就去实现一下:

首先在order-service服务中,给OrderService类添加一个queryGoods方

image-20230220162150603

在order-service的OrderController中,修改/order/query端点的业务逻辑:

image-20230220162350687

然后在order-service的OrderController中,修改/order/save端点,模拟新增订单:

image-20230220162556957

默认情况下,OrderService中的方法是不被Sentinel监控的,需要我们自己通过注解来标记要监控的方法。

给OrderService的queryGoods方法添加@SentinelResource注解:

image-20230220162842890

链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。

我们需要关闭这种对SpringMVC的资源聚合,修改order-service服务的application.yml文件:

image-20230220163243591

重启服务,访问/order/query和/order/save,可以查看到sentinel的簇点链路规则中,出现了新的资源:

image-20230220165021883

我们可以看到order/save 和 order/query 变成了两个独立的链路,在这之前没有关闭context 整合的时候,它俩还是属于同一个根链路下的两个子链路。

解下来我们就可以给这个 goods 去添加流控规则,上面有两个,我们可以随意选择一个,这两个goods 其实是同一个。

image-20230220170006945

这样链路规则就配置好了,接下来我们就利用Jmeter 去做测试。(现在我们只对query做限制)

image-20230220170306967

可以看到这里200个用户,50秒内发完,QPS为4,超过了我们设定的阈值2

一个http请求是访问/order/save:

image-20230220170339124

一个http请求是访问/order/query:

image-20230220170349160

运行的结果:

sava:

image-20230220172122074

query:

image-20230220172141809

我们可以看到save不受任何影响,query 都是俩个俩个失败的,这就是根据来源请求做限流。

5.3 流控效果

前面我们已经学习完了流控模式,接下来我们学习流控效果。什么是流控效果呢?

流控效果是指请求达到流控阈值时应该采取的措施,包括三种:

  • 快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。所以我们之前在做测试的时候会发现,一旦服务触发了限流,那就会得到一个异常状态码(429),抛出的信息就是flow limiting 就是被限流了。

  • warm up:预热模式,与快速失败相似,都是对超出阈值的请求同样是拒绝并抛出异常。但它们不同的地方在于这种模式阈值会动态变化,预热模式从一个较小值逐渐增加到最大阈值。

  • 排队等待:它前面的模式不一样,它不会立即抛出异常,而是让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长,如果大于,就会被拒绝并抛出异常。

5.3.1 warm up:预热模式

我们先来学习 warm up:预热模式。

这个预热模式,它同样会把超出阈值的请求直接拒绝,并且抛出异常,但特殊之处在于,它的阈值不是一成不变的。这种方案是来应对服务冷启动的方案,那什么是服务冷启动呢?

这就像一个人,你要去做一些剧烈的运动之前,你肯定得先做一些拉伸的运动,给你的身体做一个预热,如果不做,你很容器在运动中;拉伤自己的肌肉。

那服务器也一样,服务器它的最大QPS 能够达到 比如说是10,但是它刚刚启动,你立马就直接把QPS打满,它可能还没有反应过来呢,就被你打懵了。它挂了,所以说呀,我们的服务刚刚启动时,不能上来就把QPS打满。

怎么办呢?

在预热模式中,初始的请求阈值初始值 = maxThreshold(最大阈值) / coldFactor(冷启动因子),持续指定时长后,逐渐提高到maxThreshold值。而coldFactor的默认值是3。

预热模式就是为了避免冷启动那一刻避免过高并发导致故障。

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

image-20230220180143994

案例:

我们给/order/{orderId}这个资源设置限流,最大QPS为10,利用warm up效果,预热时长为5秒

image-20230220194556055

Jmeter测试:

image-20230220194634140

QPS为10.

image-20230220194837355

刚刚启动时,大部分请求失败,成功的只有3个,说明QPS被限定在3:

随着时间推移,成功比例越来越高:

image-20230220194903517

到Sentinel控制台查看实时监控:

image-20230220194928287

一段时间后:

image-20230220195039828

5.3.2 排队等待

我们之前讲的快速失败和warm up 会拒绝新的请求并抛出异常,而排队等待则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。

后来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。

举个栗子:

​ QPS等于5(一秒钟5个请求),意味着每200ms处理一个队列中的请求;那Sentinel 就会严格去执行这个时间间隔,前面一个请求执行完,第二个请求一定要等够200毫秒。

​ 比如说前面的请求执行小于200毫秒,不管那么多,第二个一定要等够200毫秒才行。所以这个200毫秒叫预期等待时间。

​ 那我们就可以换算一下,我的前面已经有5个请求了,我要等待多久?1秒。这个就叫预期等待时长。

​ timeout = 2000,意味着预期等待超过2000ms的请求会被拒绝并抛出异常。

现在,第1秒同时接收到10个请求,但第2秒只有1个请求,此时QPS的曲线这样的:

image-20230221135854753

如果使用队列模式做流控,所有进入的请求都要排队,以固定的200ms的间隔执行,QPS会变的很平滑:

image-20230221135931069

平滑的QPS曲线,对于服务器来说是更友好的。

我们接下来去实现一个案例,给/order/{orderId}这个资源设置限流,最大QPS为10,利用排队的流控效果,超时时长设置为5s。

image-20230221140247042

然后我们利用Jmeter进行测试

image-20230221140452265

QPS为15,已经超过了我们设定的10。

如果是之前的 快速失败、warmup模式,超出的请求应该会直接报错。

但是我们看看队列模式的运行结果:

image-20230221140714503

全部都通过了。

再去sentinel查看实时监控的QPS曲线:

image-20230221141247920

看后面那一段,QPS中间非常平滑,一致保持在10,我们发的明明是15,但通过的却是10,那多余的请求到哪里去了?是不是到队列里面等待执行去了,因此你可以看到响应时间(等待时间)会越来越长。

当队列满了以后,才会有部分请求失败。

5.4 热点参数限流

5.4.1.全局参数限流

这一章节我们来学习一个特殊的限流,热点参数限流。那它特殊在哪里呢?

我们前面所学习的限流,在去统计资源的QPS的时候,会统计进入该资源的所有请求,然后判断它有没有超过QPS阈值。

而热点参数限流是分别统计参数值相同的请求,判断它有没有超过阈值。什么意思?

比方说,我现在有一个资源是根据ID查询商品。

image-20230223164126458

现在有4个请求过来了。

image-20230223164221953

如果是按照原来的统计方式,那我的QPS就是4,而按照热点参数,它会根据参数值来去判断,那前三个的请求的ID都为1.而最后一个传递ID为2。

image-20230223164433226

那QPS就会分开统计了,ID为1的统计一下为3,ID为2的统计一下为1。

配置示例:

image-20230223164652755

在这里比较关键的就是这三个配置,第一是参数索引,这里给了0,代表的是当前这个资源的参数列表中的第0索引,就是第一个参数。

单机阈值为5还有统计窗口时长1,这两合在一起就是指一秒钟最多五个请求。

那整个配置的含义就是给hot这个资源的0号参数(第一个参数)做统计,每1秒相同参数值的请求数不能超过5。

5.4.2.热点参数限流

刚才的配置中,对查询商品这个接口的所有商品一视同仁,QPS都限定为5.

而在实际开发中,可能部分商品是热点商品,例如秒杀商品,我们希望这部分商品的QPS限制与其它商品不一样,高一些。那就需要配置热点参数限流的高级选项了:

image-20230223165310702

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

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

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

案例:

给/order/{orderId}这个资源添加热点参数限流,规则如下:

  • 默认的热点参数规则是每1秒请求量不超过2

  • 给102这个参数设置例外:每1秒请求量不超过4

  • 给103这个参数设置例外:每1秒请求量不超过10

!!!!!!!

注意事项:热点参数限流对默认的SpringMVC资源无效,需要利用@SentinelResource注解标记资源!!!!!

所以我们要做的第一件事不是来配置规则,而是去修改代码添加注解。

我们先给给order-service中的OrderController中的/order/{orderId}资源添加注解。

image-20230223181643468

重启一下服务。

访问该接口,可以看到我们标记的hot资源出现了:

image-20230223182112995

这里不要点击hot后面的按钮,页面有BUG

点击左侧菜单中热点规则菜单:

image-20230223182505283

点击新增

image-20230223182527763

填写表单

image-20230223182654939

点击新增,打开jenkins。

image-20230223183528386

包含3个http请求:

普通参数,QPS阈值为2

image-20230223183616405

运行结果:

image-20230223183646694

例外项,QPS阈值为4

image-20230223183709675

运行结果:

image-20230223183752404

例外项,QPS阈值为10

image-20230223183835184

运行结果:

image-20230223183845745

相关文章:

微服务保护 -- 初识 Sentinel(雪崩问题,快速入门Sentinel)

大家好&#xff0c;今天我们要来学习阿里巴巴开源的流量控制和熔断降级框架 – Sentinel 。 1、雪崩问题及解决方案 首选我们来了解一下雪崩问题及其解决方案&#xff0c;我们学习这个微服务保护&#xff0c;其实就是为了去应对类似于雪崩问题这样的服务故障。 1.1 什么是雪…...

软件测试面试问答

笔试 笔试的话我们需要揣测具体会考什么内容&#xff0c;我们可以通过招聘信息去了解该公司需要什么样的技能&#xff0c;以此来准备笔试。一般必考的内容会有编程&#xff0c;测试用例设计&#xff0c;工作流程&#xff0c;逻辑思维等内容&#xff0c;除此之外每个公司可能还会…...

【架构】架构师的核心能力-抽象能力

文章目录一、通过归纳法找共性二、通过演绎法找关系三、通过归纳法找特性四、最后架构的核心是管理复杂度&#xff0c;架构师的核心能力是抽象能力&#xff0c;什么是抽象能力&#xff1f;抽象能力就是一种化繁为简的能力。何为化繁为简&#xff1f;就是把一种复杂的事情变得简…...

前端一面常见react面试题(持续更新中)

React 组件中怎么做事件代理&#xff1f;它的原理是什么&#xff1f; React基于Virtual DOM实现了一个SyntheticEvent层&#xff08;合成事件层&#xff09;&#xff0c;定义的事件处理器会接收到一个合成事件对象的实例&#xff0c;它符合W3C标准&#xff0c;且与原生的浏览器…...

亥姆霍兹线圈测量系统

亥姆霍兹线圈[Helmholtz线圈]是指由具有相同线圈匝数、相同线圈绕制方式且线圈半径等于线圈间距的一对或者多对线圈构成的线圈组合。 根据线圈的形状&#xff0c;亥姆霍兹线圈可分为圆形亥姆霍兹线圈和方形亥姆霍兹线圈&#xff1b;根据磁场方向&#xff0c;亥姆霍兹线圈可分为…...

JavaScript 类型转换

Number() 转换为数字&#xff0c; String() 转换为字符串&#xff0c; Boolean() 转化为布尔值。JavaScript 数据类型在 JavaScript 中有 5 种不同的数据类型&#xff1a;stringnumberbooleanobjectfunction3 种对象类型&#xff1a;ObjectDateArray2 个不包含任何值的数据类型…...

Spring Batch 综合案例实战-项目准备

目录 案例需求 分析 项目准备 步骤1&#xff1a;新开spring-batch-example 步骤2&#xff1a;导入依赖 步骤3&#xff1a;配置文件 步骤4&#xff1a;建立employee表与employe_temp表 步骤5&#xff1a;建立基本代码体系-domain-mapper-service-controller-mapper.xml …...

STM32CubeMX串口USART中断发送接收数据

本文代码使用 HAL 库。 文章目录前言一、中断控制二、USART中断使用1. 中断优先级设置 &#xff1a;2. 使能中断3. 使能UART的发送、接收中断4. 中断收发函数5. 中断处理函数6. 中断收发回调函数三、串口中断实验串口中断发送数据点亮 led&#xff1a;实验现象&#xff1a;总结…...

JavaScript Web Workers使用流程

背景 Web Workers是一个API&#xff0c;允许在浏览器中运行后台处理任务&#xff0c;而不影响用户界面&#xff08;UI&#xff09;线程的稳定性。 Web Workers 可用于消除阻止 UI 的耗时任务&#xff0c;如图表生成&#xff0c;物理模拟或数据分析等&#xff1a; 使用 Web W…...

数据结构与算法(五):优先队列

这节总结一下优先队列的常用实现方法。 一、基本概念 普通的队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。在优先队列中&#xff0c;元素被赋予优先级。当访问元素时&#xff0c;具有最高优先级的元素最先删除。优先队列具有最高级…...

二叉树的前序遍历-java两种方式-力扣144

一、题目描述给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。示例 1&#xff1a;输入&#xff1a;root [1,null,2,3]输出&#xff1a;[1,2,3]示例 2&#xff1a;输入&#xff1a;root []输出&#xff1a;[]示例 3&#xff1a;输入&#xff1a;root [1]输出…...

浅析 Redis 主从同步与故障转移原理

我们在生产中使用 Redis&#xff0c;如果只部署一个 Redis 实例&#xff0c;当该实例宕机&#xff0c;到恢复之前都不可用&#xff1b;虽说 Redis 一般都用来做缓存&#xff0c;但不可用给业务系统带来的影响也是不小的&#xff0c;流量大时甚至会导致整个服务宕机。所以 Redis…...

MyBatis学习笔记(七) —— 特殊SQL的执行

7、特殊SQL的执行 7.1、模糊查询 模糊查询的三种方式&#xff1a; 方式1&#xff1a;select * from t_user where username like ‘%${mohu}%’ 方式2&#xff1a;select * from t_user where username like concat(‘%’,#{mohu},‘%’) 方式3&#xff1a;select * from t_u…...

计算机组成原理(1)--计算机系统概论

一、计算机系统简介1.计算机系统软硬件概念计算机系统由“硬件”和“软件”两大部分组成。所谓“硬件”&#xff0c;是指计算机的实体部分&#xff0c;它由看得见摸得着的各种电子元器件&#xff0c;各类光、电、机设备的实物组成&#xff0c;如主机、外部设备等。所谓“软件”…...

jdbc模板的基本使用

1.JdbcTemplate的开发步骤 <1>导入spring-jdbc和spring-tx坐标 <2>创建数据库表和实体 <3>创建JdbcTemplate对象 <4>执行数据库 2.JdbcTemplate快速入门 <1>导入坐标 <dependency><groupId>org.springframework</groupId><…...

JPA 注解及主键生成策略使用指南

JPA 注解 Entity 常用注解 参考&#xff1a;JPA & Spring Data JPA学习与使用小记 指定对象与数据库字段映射时注解的位置&#xff1a;如Id、Column等注解指定Entity的字段与数据库字段对应关系时&#xff0c;注解的位置可以在Field&#xff08;属性&#xff09;或Prope…...

【C语言刷题】找单身狗、模拟实现atoi

目录 一、找单身狗 1.暴力循环法 2.分组异或法 二、模拟实现atoi 1.atoi函数的功能 2.模拟实现atoi 一、找单身狗 题目描述&#xff1a;给定一个数组中只有两个数字是出现一次&#xff0c;其他所有数字都出现了两次。 编写一个函数找出这两个只出现一次的数字。 比如&…...

前端必会面试题指南

计算属性和watch有什么区别?以及它们的运用场景? // 区别computed 计算属性&#xff1a;依赖其它属性值&#xff0c;并且computed的值有缓存&#xff0c;只有它依赖的属性值发生改变&#xff0c;下一次获取computed的值时才会重新计算computed的值。watch 侦听器&#xff1a…...

C 语言—— 数组

【C 语言】数组1. 概念2. 声明3. 分类4. 初始化5. 赋值6. 附加语法7. VLA 的一些补充1. 概念 数组是存放一组 相同类型 的 有序 数据的一段 连续 空间。 2. 声明 TYPE identifier[static(optional) qualifiers(optional) expression(optional)] TYPE identifier[qualifiers(o…...

Oracle-RAC集群主机重启问题分析

问题背景: 在对一套两节点Oracle RAC19.18集群进行部署时&#xff0c;出现启动数据库实例就会出现主机出现重启的情况&#xff0c;检查发现主机重启是由于节点集群被驱逐导致​。 问题: 两节点Oracle RAC19.18集群,启动数据库实例会导致主机出现重启。 问题分析: 主机多次出现…...

Python每日一练(20230227)

目录 1. 路径交叉 ★★★ 2. 缺失的第一个正数 ★★★ 3. 寻找两个正序数组的中位数 ★★★ 附录 散列表 基本概念 常用方法 1. 路径交叉 给你一个整数数组 distance 。 从 X-Y 平面上的点 (0,0) 开始&#xff0c;先向北移动 distance[0] 米&#xff0c;然后向西移…...

Scratch少儿编程案例-算法练习-存款收益计算

专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...

【Linux驱动开发100问】Linux驱动开发工程师在面试中常被问到的问题汇总

&#x1f947;今日学习目标&#xff1a;什么是Kconfig&#xff1f;如何使用Kconfig&#xff1f; &#x1f935;‍♂️ 创作者&#xff1a;JamesBin ⏰预计时间&#xff1a;10分钟 &#x1f389;个人主页&#xff1a;嵌入式悦翔园个人主页 &#x1f341;专栏介绍&#xff1a;Lin…...

每日学术速递2.27

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CL 1.FiTs: Fine-grained Two-stage Training for Knowledge-aware Question Answering 标题&#xff1a;FiTs&#xff1a;用于知识感知问答的细粒度两阶段训练 作者&#xff1a;Qichen…...

【数据库系统概论】基础知识总结

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…...

简单移动平均在量化中的应用(附Python实战代码)

在大多数金融产品的投资过程中,均线系统都是很重要的投资参考。一般来说,均线可以近似理解为某段时间内成交筹码的均价,它往往能帮助我们找到合适的支撑位和压力位。随着各种技术流派以及统计学的发展,从简单移动平均中逐渐衍生出了更多的均线计算方式,比如指数移动平均、…...

ChatGPT提高你日常工作的五个特点,以及如何使用它来提高代码质量

ChatGPT已经完全改变了代码开发模式。然而&#xff0c;大多数软件开发者和数据专家们仍然不使用ChatGPT来完善——并简化他们的工作。 这就是我们在这里列出提升日常工作效率和质量的5个不同的特点的原因。 让我们一起来看看在日常工作中如何使用他们。 警告&#xff1a;不要…...

spark datasourceV1和v2

datasourceV2 一文理解 Apache Spark DataSource V2 诞生背景及入门实战 https://zhuanlan.zhihu.com/p/83006243 2.3 Data source API v2 https://issues.apache.org/jira/browse/SPARK-15689 Because of the above limitations/issues, the built-in data source impleme…...

10种聚类算法的完整python操作示例

大家好&#xff0c;聚类或聚类分析是无监督学习问题。它通常被用作数据分析技术&#xff0c;用于发现数据中的有趣模式&#xff0c;例如基于其行为的客户群。有许多聚类算法可供选择&#xff0c;对于所有情况&#xff0c;没有单一的最佳聚类算法。相反&#xff0c;最好探索一系…...

构建合作伙伴生态系统刻不容缓

合作伙伴关系管理(PRM)系统是否已死&#xff1f;向合作伙伴生态系统的转变将如何改变我们未来管理合作伙伴计划的方式&#xff1f; 自PC革命以来&#xff0c;间接销售和渠道营销一直普遍存在于技术领域&#xff0c;通过其他公司的销售团队和人脉来增加销售&#xff0c;是一种明…...

wordpress 斜杠/百度趋势搜索

自带的底部导航 在 app.json 中添加 &#xff0c; 所有小程序的页面都会显示出来 {"tabBar": {"list": [{"pagePath": "pages/index/index","iconPath":"","text": "首页"},{"pagePat…...

出名的网站建设软件/苏州百度推广

点击上方蓝色字关注我们~十八载执着创新云计算一马当先自主可控心中念未来征途尤可期在云计算刚出现时&#xff0c;很多人认为中国厂商弯道超车的机会来了。以OpenStack、Ceph为例&#xff0c;他们在中国市场发展的强劲势头甚至超过国外。无论是云计算企业、创业公司&#xff0…...

国外大神的平面设计网站有哪些/网站怎么优化seo

数据库索引编辑锁定索引是对数据库表中一列或多列的值进行排序的一种结构&#xff0c;使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她&#xff0c;则与在表中搜索所有的行相比&#xff0c;索引有助于更快地获取信息。索引的一个主要目的就是加快检…...

东莞网站建设及外包/手机营销推广方案

开创了自走棋玩法的巨鸟多多的《多多自走棋》&#xff0c;最终还是“停运”了。就在昨日&#xff0c;《多多自走棋》的官博发布公告&#xff0c;表示腾讯将于8月5日11点正式停止《多多自走棋》中国大陆地区的运营&#xff0c;届时游戏充值渠道和新用户注册功能将关闭&#xff0…...

新疆生产建设兵团人社厅网站/衡水seo营销

一、题目[LeetCode-38] 给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) &quo…...

网站空间期限查询/友情链接qq群

文章目录一、配置数据源-mysql二、下载安装1.1 下载包安装(已验证)1.2 Github 上下载源码(未验证)1.3 docker安装(已验证)三、springCloud pom主要配置3.1 pom3.2 bootstrap.yaml部分配置3.3 nacos设置对应一、配置数据源-mysql a:配置数据库 /*Navicat Premium Data Transfe…...