Sentinel

Posted by Futari on 2023-02-23
Estimated Reading Time 8 Minutes
Words 2.5k In Total
Viewed Times

雪崩效应和Sentinel流控

雪崩效应是多个服务之间来进行调用时,如果被调用的服务。不可用,那么就会导致调用服务的服务器的线程不断的累积,直到资源崩溃,偶尔产生雪崩,由于是服务之间的级联,所以也叫做级联失效或级联故障 (cascading failure)

Snipaste_2023-02-23_18-14-19.png

服务容错

为了避免产生雪崩效应,所以说我们产生了服务容错的思想,服务容错我们常用的有。超时,限流,仓壁模式,断路器模式

>

超时是指如果我们发送请求在一定的时间没有收到回应,那么我们就认为被调用方不可用,那么我们就将该进程标记为失败

限流也就是我们规定好在一段时间内的一个请求次数,超过之后直接启用我们的拒绝策略

仓壁模式是指我们将一个微服务,比如说我们按controller来进行划分,每一个controller作为一个仓壁,仓壁之间互不影响,如果一个仓壁满之后,我们对这个仓库进行单独的拒绝,而不影响其他的仓壁

断路器模式。是比较智能的模式,我们断路器首先是处于关闭状态,假如说我们的服服务调用次数到达了我们的一个阈值并且还是调用失败,那么我们断路器打开,不再进行服务调用,等待我们的一个断路器的时间窗口结束之后,断路器处于半开状态,假如说此时发送一个请求仍然失败,那么仍然将我们的一个断路器打开,如果发送该请求成功了,那么我们就将断路器关闭,代表我们的服务可用了,如下图

Snipaste_2023-02-23_18-23-42.png

我们通过整合Sentinel进行服务,加入依赖之后,添加以下的配置并启动

Snipaste_2023-02-23_18-27-04.png

下载我们的sentinelServer,打开我们的8080端口,登录到控制台页面,可以发现我们使用到的接口或者被访问过的路径都会进入到我们的流控规则里。

Snipaste_2023-02-23_18-29-02.png

配置流控规则

我们的资源名一般默认是路径,但是我们只要做到唯一区分其实就可以了

针对来源我们可以default默认是所有的应用,我们可以单独设置A服务,那么代表我们这个流控规则呢,仅对a服务的请求起流控作用
流控模式我们可以选择直接关联或者是链路

(1)直接代表就是对本服务的一个限流
(2)关联我们要添加关联路径也就是服务路径,假如关联路径的服务到达了预值,那么我们就限流本服务,这个应用的范围很广泛,比如说我们一个查询一个新增服务,假如说我们的新增到达了预值,那么我们就去限流我们的查询来减轻服务器的压力
(3)链路要规定好入口资源,其实和针对来源很像,但是针对来源的我们是针对的微服务的来源,写的是服务名,而我们的入口资源呢则是写的接口名,所以链路流控呢是针对来源的更细粒度的流控。

Snipaste_2023-02-23_18-29-52.png

至于流控效果,快速失败也就是直接拒绝,而warm up如下:

比如我们的预值设置为300,而我们的因子默认是3,那么我们除出来是100,而我们的预热时间是十秒,那么我们就需要经过十秒再达 到我们的100的阈值,而不是比如秒杀,立刻达到我们的峰值,使用一种缓慢的策略

立刻达到我们的100峰值,可能会将我们的服务器打挂,所以我们让他十秒钟再预热到我们的100,这样来保证我们的服务器不会立刻的挂掉

Snipaste_2023-02-23_18-37-35.png

排队等待如下所示,但是呢要自己设定一个超时时间,假如说匀速排队超过了自己的时间,还没有排上队,那么就会将该请求扔掉

Snipaste_2023-02-23_18-42-13.png

降级规则

降级规则其实也就是断路器模式,rt是平均响应时间

Snipaste_2023-02-23_18-50-41.png

上图代表:

Snipaste_2023-02-23_18-51-40.png

Snipaste_2023-02-23_18-52-00.png

异常数和异常比例其实都是统计,但是可能统计的量度不同

Snipaste_2023-02-23_18-53-01.png

Snipaste_2023-02-23_18-53-27.png

热点规则

热点规则类似于流控规则,只不过可以理解成更细粒度的流控规则,因为我们的热点规则其实针对于接口,也就是API,如下图所示。
因为我们的方法参数有很多,所以我们的参数索引从0开始标记
参数例外项是指我们规定好的热点限流的某个参数,如果我们想要针对特定的值,比如说1或者是2或者是3,规定好他的一个阈值不在上面的一个范围内,就可以单独设立他的预值

注意我们的热点规则参数类型只适合于我们的一个string和八大基本数据类型

Snipaste_2023-02-23_19-21-49.png

系统规则(意如其名)

Snipaste_2023-02-26_17-31-00.png

Snipaste_2023-02-26_17-32-02.png

Snipaste_2023-02-26_17-32-42.png

授权规则(资源的)

授权规则就是指使用流控应用是否可以访问具体的资源,相当于设定了权限

PS: Sentinel其实是支持代码配置的,我们可以通过配置具体的属性类来进行配置,所以说我们在控制台来进行配置,只是一种可视化的方式,配置模式上还是使用类来进行配置

Sentinel控制台和微服务通信原理

类似于服务发现机制

Snipaste_2023-02-26_17-51-48.png

客户端和控制台配置项

Snipaste_2023-02-26_17-52-47.png

启动jar包也就是启动控制台时加入后缀配置选项

Snipaste_2023-02-26_17-54-43.png

API

Snipaste_2023-02-26_19-17-11.png
第一个API是最核心的API,用于定义资源,让资源受到监控并保护资源

第二个可以对传入的参数。也就是具体的异常进行统计

第三个可以实现调用来源,标记调用,比如在限流规则中配置来源时就可以直接传入自己在第三个API传入的。来源名

@SentinelResource(注解类的底层还是API)

Snipaste_2023-02-26_19-27-52.png

Snipaste_2023-02-26_19-29-25.png

RestTemplate整合Sentinel

Snipaste_2023-03-01_10-17-07.png

添加该注解之后可以直接配置流控规则,原因是该注解完成了Sentinel与http客户端的整合,底层使用了mvc的拦截器,源码在的后置处理器中,对于页面的异常展示,因为该注解里面有很多的属性,我们仍然可以通过配置blockhandler和fallback。等属性配置异常处理器

Feign整合Sentinel

Snipaste_2023-03-01_11-38-29.png

使用方法:需要在加@feignclient的接口上,将该注解的属性添加fallback或Fallbackfactory,指向具体类名,那么具体类就去实现这个接口即可

Snipaste_2023-03-01_11-44-13.png

总结

Snipaste_2023-03-01_11-49-26.png

规则持久化(重点)

Snipaste_2023-03-01_11-52-05.png

Snipaste_2023-03-01_19-15-51.png

拉模式可以理解成微服务从控制台拉取我们的配置,而推模式则是控制台向我们的配置中心推送,然后我们的配置中心在向我们的具体服务推送规则

生产环境

因为我们的推拉模式各有优缺点,所以我们在常用的生产环境中,我们一般会使用阿里的ahas控制台来进行直接的配置,我们需要整合ahas的依赖,其实底层还是依靠着sentinel

Snipaste_2023-03-01_19-17-12.png

集群流控

Snipaste_2023-03-01_19-19-18.png

因为我们使用的是1.6.2的版本,我们的tokenserver。不支持高可用以及故障转移等特性,所以并不能应用于生产环境,所以此时仅作了解。

Snipaste_2023-03-01_19-19-46.png

Sentinel优化(拓展)

拓展一般都是基于CommonFilter接口,这个接口是非常关键的一个接口

(1)我们可以去实现UrlBlockHandler接口去优化我们的错误页展示,去实现对应的block方法,来对具体的异常信息进行返回

(2)我们还可以实现其他接口来实现区分来源,我们在项目的授权规则上开始时使用的是服务名来进行区分来源,在这里我们可以去实现requestOriginParser接口,比如说我们可以将Header中的属性修改,然后我们从request中拿出我们所需要的属性比对,如果符合我们的业务需求属性,那么我们才通过

(3)我们前面的都是对具体的域名资源路径来进行限流,比如IP:端口/share/1,而share是我们的路径名,这样才是我们所需要的限流接口,1只是传入的ID,那么我们如何进行配置呢?

我们同样去实现我们的UrlCleaner接口,然后去重写他的clean方法,帮我们获取到的原url进行处理,比如说将ID进行删除,或者将其统一修改为String类型的占位符,演示操作如下

Snipaste_2023-03-01_19-34-46.png

本质

Snipaste_2023-03-01_19-35-08.png

其实底层使用的都是我们的过滤器,对我们的内容来进行拦截过滤,我们可以在配置文件中将我们的。sentinel Filter enabled 属性设置为false来进行,关闭我们的commonFilter,然后我们在原有基础上进行修改扩展。

仓壁模式

还有一种仓壁模式的限流模式没有涉及,对于舱壁模式的基础想法,我们可以认为每一个controller都有它对应的一个线程池来单独对它进行限流,但是无疑如果有很多的请求路径的话,那么就会产生很多的线程池来造成很大的资源浪费
所以我们的思路一般是使用唯一的一个线程池,然后将每一个接口请求分配给定的几个线程,也就是说每个接口不能超过分配给他的线程阈值,这样的设计思想性能就会提升很大

如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !