首页 > 其他分享 >Sentinel服务保护

Sentinel服务保护

时间:2022-08-21 11:34:31浏览次数:42  
标签:服务 请求 保护 限流 链路 Sentinel QPS 资源

雪崩问题

由于微服务中的某个服务出现故障无法完成任务,导致依赖于它的服务阻塞在对它的请求上,不释放连接资源,最终连接堆积,它也无法处理新的任务,这样的情况按照层级不断传递,最终使得微服务集群中的很多节点都出现相同的故障,这就是雪崩

img

雪崩问题的原因:

  1. 瞬时高并发使得服务处理的速率跟不上请求速率
  2. 服务或网络故障

雪崩问题的解决办法:

  1. 超时处理:它能一定程度上缓解雪崩问题,但如果超时时间没有连接进入的时间快,还是会出现雪崩问题
  2. 舱壁模式(线程隔离):限定每个微服务中的每个业务能使用的最大线程数,避免耗尽连接资源
    img
    该模式还是没有完全解决问题,假设服务C已经宕机,该模式的业务2还是会不断的去访问服务C,实际上这些访问只是白白浪费资源。而且,依赖于服务A的业务2的微服务不还是会阻塞嘛,虽然整体没事,但对于这条服务调用路径来说是不是可以认为依然发生了雪崩呢?
  3. 熔断降级断路器会统计对于某个服务调用的失败比例,若比例达到一定阈值,拦截访问该业务的一切请求
  4. 流量控制(预防):限制业务访问的QPS,将大量请求按照服务所能承受的QPS传递到服务中(有点类似MQ所带来的流量削峰)

Sentinel Dashboard安装的一个坑

我想替换Sentinel默认的用户名和密码,由于Sentinel控制台是一个SpringBoot项目,所以我打算在jar包目录放置一个application.yml文件,在里面按照官方文档给的参数来配置用户名和密码,官方给的配置如下:

sentinel:
    dashboard:
        auth:
            username: xxx
            password: xxx

无论我是用这还是用命令行参数都没用,后来我把这个jar包解开了,看了下官方的配置文件里是咋写的,结果哔了个狗:

img

所以,我把我的配置文件改成:

auth:
    username: xxx
    password: xxx

现在好了...

QuicStart

在需要被监控的微服务中引入Sentinel依赖

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

在配置文件中配置:

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:10101

访问该服务的任意端点,然后去Sentinel控制台中查看被监控下来的数据:

img

同时我们可以通过簇点链路中的每个资源后面的流控按钮来控制该端口允许的最大流量

img

比如,这里我们把QPS设置为1,那么一秒钟内该资源只能被访问1次

img

一秒钟内尝试访问多次被Sentinel拦截

img

簇点链路

簇点链路是项目中的调用链路,链路中的每一个被监控的接口就是一个资源,默认情况下,Sentinel会监控SpringMVC中的每个Controller方法。

流控模式

在Sentinel流控的高级选项中,有一个流控模式选项

img

  1. 直接:当当前资源的请求到达阈值时,对当前资源进行限流
  2. 关联:当与当前相关的另一个资源的请求到达阈值时,对当前资源进行限流
  3. 链路:统计从指定链路到当前资源的请求,当触发阈值时,对指定链路限流

关联模式的示例

假设/query资源是对商品进行查询的资源,/update是支付后对商品库存进行修改的资源,我们期望/update资源的优先级更高,因为这里的用户在花钱。

所以我们可以在/update的QPS到达阈值时对/query的部分访问进行拒绝,这样也就让出了部分处理资源给/update

img

关联模式用在两个具有关联的,但一个比另一个优先级要更高的情况下

链路模式的示例

系统中有三个资源:

  1. 假设/order/query是查询订单的接口
  2. 假设/order/update是插入订单的接口
  3. 假设查询和插入订单都需要访问OrderService.queryGoods方法

还是一样的思路,我们想尽可能保证插入订单的请求被服务,因为人家花钱了。所以,我们可以针对queryGoods这个资源进行链路限流,当它是从/order/query来的,就给它一个较小的QPS,当它是从/order/update来的,就给它一个较大的QPS。

开始前的设置

Sentinel默认只会监控Controller方法作为资源,你还要将对应的Service方法声明为Sentinel资源

@SentinelResource(value = "queryGoods")
public void queryGoods() {
    System.out.println("queryGoods");
}

Sentinel默认还会开启Controller方法的context整合,虽然不知道是啥,但它会导致链路模式流控失败,可以使用以下方式关闭

spring:
  cloud:
    sentinel:
      web-context-unify: false

开启链路模式限流并测试

img

img

img

img

流控效果

高级设置中还有一个流控效果,有三种选项

  1. 快速失败:到达阈值,直接抛出FlowException,请求宣告失败
  2. warm up:效果同上,但阈值是从一个较小的值慢慢增长到最大阈值
  3. 排队等待:所有请求按照到达先后到队列中排队,新来的请求当预期等待时间超出最大时长时就会被拒绝

warm up的示例

程序刚刚启动时肯定达不到最大的QPS,随着散落在程序中、框架中、系统中的各种缓存技术、JIT优化技术的一点一点的应用,程序才能慢慢的到达最大QPS。

warm up即设定一个时间,请求阈值从threshold / coldFactor(默认为3)开始慢慢提高,等到时间到达,实际阈值才变成设定好的最大threshold

img

排队等待的示例

所有到达的请求到队列中排队,后面的请求必须等待前面的请求完成后才能执行。

img

排队等待中有一个预期等待时间的概念,当QPS=5时,意味着预期每个任务的执行时间是200ms,这时,新来的任务的预期等待时间就是队列大小 * 1000 / QPSms,而排队等待可以设置这个预期等待时间的最大值,如果新任务的预期等待时间超出这个最大值,它就会被拒绝。

img

实际上,排队等待会起到一个流量整形的作用,无论瞬时的并发量有多大,都会排到队列中慢慢处理(当超时时间够大时)。

下面是我们使用排队等待(QPS=10, timeout=10000)流控效果时,以15的QPS来发送20秒请求,但由于有队列的存在,QPS被限制在10,而且没有请求被拒绝,这都是队列的功劳。

img

当然,如果你将这个测试过程持续长些,始终以15的QPS进行发起请求,以10QPS的速度进行处理,那么队列始终会满的,然后就会出现请求被拒绝的情况,比如在当前设置下,队列最多能容纳100个请求,因为\(最大请求数 = timeout/(1000/qps)=10000/(1000/10)=100\),如果我们每秒发送15个请求,那么每秒会多出5个请求没被处理,积攒在队列中,那么,第21秒也许就有请求失败了。

所以,排队等待只是在瞬时高并发涌入时进行流量削峰填谷,如果长时间的请求QPS大于你能处理的QPS,还是多增加一些服务吧

热点参数限流

比如在微博突然发生热点事件的情况,某个博主或者某个帖子的请求访问量肯定比其它人的高很多,所以这种情况,这个博主或帖子的QPS可能需要加大,此时根据这个博主或帖子的id提供例外的限流规则比直接将博主查询和帖子查询的整个资源都应用特定的限流更加人性化。

img

下面是针对热点订单(看起来有些愚蠢就这样吧)的限流设置,默认情况下所有订单的QPS都是2,而2和3是比较热点的订单,它们的QPS是例外项,被设置成了4和10。

img

这时,需要去代码中给指定的Controller方法添加resource,这是必须的,因为Sentinel的热点参数限流对Controller那个默认被识别的资源不生效,你要想用热点参数限流就必须使用@SentinelResource重新声明它。

@GetMapping("/{id}")
@SentinelResource("hotorders")
public Order getOrderById(@PathVariable("id") Integer id) {
    return orderService.getOrderById(id);
}

标签:服务,请求,保护,限流,链路,Sentinel,QPS,资源
From: https://www.cnblogs.com/lilpig/p/16609676.html

相关文章

  • CentOS7安装Telnet服务
    CentOS7安装Telnet服务1.在安装Telnet前先检查系统是否安装了telnet-server和xinetdrpm-qatelnet-serverrpm-qaxinetd2.如果没有安装,则开始安装yum-yinstallteln......
  • 解决用公网无法连接阿里云服务器Nginx
    首先保证nginx安装无误的情况下  ./nginx-t可以通过这个命令来检测 出现这个就说明安装成功了 如果安装过程中出现一些问题 自行百度修改配置文件即可  ......
  • 注册windows服务的两种方式
    https://blog.csdn.net/Habo_/article/details/125371836 方法一使用widows自带得SC命令以管理员身份运行cmd在cmd命令行输入注册服务sccreatetest.windows.services......
  • 虚拟数字人制作应用有什么优势?AR服务商形象|广州华锐互动
      在应用行业方面,虚拟数字人也将带动文旅、教育、金融、医疗等行业的新变革。广州华锐互动致力于数字人底层核心技术的研发,积极推动尖端实验室科研成果的民用化、商业化,......
  • FireDAC使用Mormot开发Rest服务器,返回JSON数据格式的问题
    FireDAC沿用了一贯的DataSnap的数据返回方式,这也使得开发出来的REST Server很给难给第三方应用提供服务用什么办法可以解决FireDAC直接序列返回的Json只是数据信息,而不是......
  • Taurus.MVC 微服务框架 入门开发教程:项目集成:5、统一的日志管理。
    系列目录:本系列分为项目集成、项目部署、架构演进三个方向,后续会根据情况调整文章目录。本系列第一篇:Taurus.MVCV3.0.3微服务开源框架发布:让.NET架构在大并发的演......
  • 关于压测服务器差点崩溃
    昨天试着将最近写的秒杀项目部署到服务器上做压力测试。在商品详情做压测一点问题没遇上,因为还没做优化所以当时吞吐量300我觉得还ok然后下单操作的压测就突然一下子请求......
  • MAC环境nginx搭建静态资源服务器
    MAC环境nginx搭建静态资源服务器安装nginxmac环境nginx比较简单,使用命令安装即可brewinstallnginx查看nginx信息brewinfonginx启动命令:launchctl命令启动注意......
  • 如何在Spring Boot Rest服务方法中设置响应头值
    如何在SpringBootRest服务方法中设置响应头值问题描述新手问题...我正在构建我的第一个SpringBootRestful服务.我的静态服务设计要求在响应头中返回一些数据. 推荐......
  • windows10+ffmpeg+rtmp+nginx流媒体服务配置
    一、概述案例:由于要测试Android播放客户端和推流客户端所以需要配置一个简单的流媒体服务器,采用nginx+rtmp服务搭建参考博客下载:链接:https://pan.baidu.c......