【开发】微服务整合Sentinel

目录

前言

1W:什么是Sentinel?

2W:为什么使用Sentinel?

3W:如何使用Sentinel?

1. 在pom.xml中导入Sentinel依赖坐标

2. 配置控制台

3.  访问API接口的任意端点

流量控制

1. 簇点链路

2. 快速入门

流控模式

1. 直接模式

2. 关联模式

 3. 链路模式

4. 总结

流控效果

1. warm up

2. 排队等待

3. 总结

热点数据限流

1. 标记资源

隔离和降级

FeignClient整合Sentinel

1.修改配置,开启sentinel功能

2. 编写失败降级逻辑

方式①

方法②

3.线程隔离(舱壁模式)

总结


前言

在整合Sentinel前,我们需要了解一下微服务中的雪崩问题:

雪崩问题:在微服务中,如果服务提供者发生了故障,当前应用的部分业务因为依赖于该服务,因此也会被阻塞。请求一直阻塞,会导致服务器资源耗尽,从而导致其他服务都不可用,形成级联失败,从而形成雪崩问题。

1W:什么是Sentinel

  • Sentinel是阿里巴巴开源的一款微服务流量控制组件。

Sentinel官网icon-default.png?t=N7T8https://sentinelguard.io/zh-cn/index.html

2W:为什么使用Sentinel?

  • 丰富的应用场景:Sentinel承接了阿里巴巴近10年来的双十一大促流量的核心场景,例如秒杀(突发流量控制在系统容量的可承受范围内)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel提供实时监控功能。可以在控制台中看到接入到应用的单台机器秒级数据,甚至500台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel提供开箱即用的与其他开源框架/库的整合模块,例如与Spring CloudDubbogRPC的整合。我们只需要引入相关的依赖并进行简单的配置即可快速地接入Sentinel
  • 完善的SPI扩展点:Sentinel提供简单易用、完善的SPI扩展接口。我们可以通过实现扩展接口来快速地定制逻辑。例如:定制规则管理、适配动态数据源等

3W:如何使用Sentinel?

1. 在pom.xml中导入Sentinel依赖坐标

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2021.1</version>
</dependency>

2. 配置控制台

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

spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:[端口号]

3.  访问API接口的任意端点

打开浏览器,访问http://localhost:端口号/API接口,触发sentinel的监控。

然后访问sentinel控制台

默认路径为:http://localhost:8080页面

默认登录账号:sentinel

默认登录密码:sentinel


流量控制

限流是避免服务因突发的流量而发生故障。

1. 簇点链路

当请求进入微服务时,会首先访问DispatcherServlet,然后进入ControllerServiceMapper,这样的一个调用链叫做簇点链路。

簇点链路中被监控的每一个接口都是一个资源。

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

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

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

2. 快速入门

点击资源/order/prod/{pid}后面的流控按钮,弹出表单。

QPS:线程数(用户数量)/用户访问时间 =请求数/秒,即每秒的响应请求数,也就是最大吞吐量。

  1. sentinel控制台添加限流规则,QPS的单机阈值为五,然后测试。
  2. 利用jmeter测试;

20个用户,2秒内运行完,QPS是10,超过了5

选中流控入门,QPS<5 右击运行:

 结果:成功的请求每次只有5个


流控模式

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

  • 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认模式;
  • 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流;
  • 链路:统计从指定链路访问到本资源的请求时,触发阈值时,对指定链路限流;

1. 直接模式

 快速入门测试就是直接模式。


2. 关联模式

关联模式:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流;

配置规则:

语法说明:/write资源访问量触发阈值时,就会对/read资源限流,避免影响/write资源

使用场景:比如用户支付时需要修改订单状态,同时用户要查询订单。查询和修改操作会争抢数据库锁,产生竞争。业务需求是优先支付和更新订单的业务,因此当修改订单业务触发阈值时,需要对查询订单业务限流。

需求说明:

  • 添加两个新的端点:/order/query/order/update
@GetMapping("/order/query")
public String queryOrder(){
    return "查询订单成功";
}
@GetMapping("/order/update")
public String updateOrder(){
    return "更新订单成功";
}
  • 配置流控规则,当/order/update资源被访问的QPS超过5时,对/order/query请求限流

可以看到1000个用户,100秒,QPS为10,超过了设置的阈值:5

请求的目标是/order/update,这样这个端点就会触发阈值

但限流的目标是/order/query,我们在浏览器访问,发现:确实被限流了


 3. 链路模式

链路模式:统计从指定链路访问到本资源的请求时,触发阈值时,对指定链路限流;

配置示例:

例如有两条请求链路:

  • /test1 --> /common
  • /test2 --> /common
  • 如果只希望统计从/test2进入到/common的请求,可以这样配置:

需求说明:

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

public void queryGoods(){
    System.err.println("查询商品");
}

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

@GetMapping("/order/query")
public String queryOrder(){
    //查询商品
    orderService.queryGoods();
    //查询订单
    System.out.println("查询订单");
    return "查询订单成功";
}

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

@GetMapping("/order/save")
public String saveOrder(){
    //查询商品
    orderService.queryGoods();
    //查询订单
    System.out.println("新增订单");
    return "新增订单成功";
    
}

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

@SentinelResource("goods")
public void queryGoods(){
    System.err.println("查询商品");
}

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

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

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

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

添加流控规则

点击goods资源后面的流控按钮,在弹出的表单中填写下面信息:

 只统计从/order/query进入/goods的资源,QPS的阈值为2,超出则被限流。

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

一个http请求是访问/order/save:运行的结果:完全不受影响


4. 总结

流控模式有哪些?

  • 直接:对当前资源限流;
  • 关联:高优先级资源触发阈值,对低优先级资源限流;
  • 链路:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流;

流控效果

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

  • 快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式;
  • warm up:预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值;
  • 排队等待:让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长;

1. warm up

warm up也叫预热模式,是应对服务冷启动的一种方案。请求阈值初始值是maxThreshold / coldFactor,持续指定时长后,逐渐提高到maxThreshold值。而coldFactor的默认值是3;

需求说明:

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

 刚刚启动时,大部分请求失败,成功的只有3个,说明QPS被限定在3:随着时间推移,成功比例越来越高;


2. 排队等待

当请求超过QPS阈值时,快速失败和warm up会拒绝新的请求并抛出异常。

排队等待是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后面的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。

需求说明:

/order/prod/{pid}这个资源设置限流,最大QPS为10,利用排队的流控效果,超时时长设置为5s

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

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

 全部通过

 QPS非常平滑,一致保持在10,但超出的请求没有被拒绝,而是放入队列。


3. 总结

流控效果:

  • 快速失败:QPS超出阈值时,拒绝新的请求;
  • warm up:QPS超出阈值时,拒绝新的请求;QPS阈值是逐渐提升,可以避免冷启动时高并发导致服务器宕机;
  • 排队等待:请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝;

热点数据限流

分别统计参数值相同的请求,判断是否超过QPS阈值。

案例需求:给/order/prod/{pid}这个资源加热点参数限流,规则如下:

  • 默认的热点参数规则是每1秒请求量不超过2;
  • 给1这个参数设置例外:每1秒请求量不超过4;
  • 给19这个参数设置例外:每1秒请求量不超过10;

注:热点参数限流对默认的Spring MVC资源无效,需要利用@SentinelResouce注解标记资源

1. 标记资源

shop-order中的OrderController中的/order/prod/{pid}资源添加注解:

@SentinelResouce("hot")

访问该接口,可以看到我们标记的hot资源出现了:这里不要点击hot后面的按钮,页面有bug

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

Jmeter测试

这里发起请求的QPS为5,包含3个http请求:

普通参数,QPS阈值为2

运行结果:每次成功2个请求

例外项,QPS阈值为4

运行结果:每次成功4个请求

例外项,QPS阈值为10

运行结果:每次成功所有请求


隔离和降级

线程隔离:调用者在调用服务提供者时,给每个调用的请求分配独立线程池,出现故障时,最多消耗这个线程池内资源,避免把调用者的所有资源耗尽

熔断降级:调用方这边加入断路器,统计对服务提供者的调用,如果调用的失败比例过高,则熔断该业务,不允许访问该服务的提供者

不管是线程隔离还是熔断降级都是对客户端的保护

FeignClient整合Sentinel

SpringCloud中,微服务调用都是通过Feign来实现的,因此做客户端保护必须整合FeignSentinel

1.修改配置,开启sentinel功能

修改shop-Orderapplication.yml文件,开启FeignSentinel

feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持
2. 编写失败降级逻辑

业务失败后,不能直接报错,而应该返回用户一个友好提示或者默认结果,这个就是失败降级逻辑

给FeignClient编写失败后的降级逻辑

方式一:FallbackClass,无法对远程调用的异常做处理

方法二:FallbackFactory,可以对远程调用的异常做处理

  • 方式①

步骤一:配置yml文件开启支持

feign:
  sentinel:
    enabled: true

步骤二:创建ProductServiceFallBack类实现降级方案编辑

@Component
public class ProductServiceFallBack implements IProductService{

       @Override
       public Product findByPid(Integer pid){
           Product product = new Product();
           product.setPid(-1);
           product.setPname("暂无商品");
           return product;
       }

}

步骤三:配置属性

@FeignClent(value="service-product",fallbackFactory = ProductServiceFallBack.class)
  • 方法②

步骤一:配置yml文件开启支持

feign:
    sentinel:
        enabled: true

 步骤二:创建ProductServiceFallBack类实现降级方案编辑

@Component
public class ProductServiceFallBack implements FallBackFactory<ProductService>{
    @Override
    public ProductService create(Throwable throwable){
        return new ProductService(){
        @Override
            public Product findByPid(Integer pid){
                System.out.println("异常信息:"+throwable);
                Product product = new Product();
                product.setPid(-1);
                product.setPname("暂无商品");
                return product;        
            }
        };
    }
}

步骤三:配置属性

@FeignClient(value="service-product",fallbackFactory = ProductServiceFallBack.class)
3.线程隔离(舱壁模式)
  • 线程池隔离:给每个服务调用业务分配一个线程池,利用线程池本身实现隔离效果
  • 信号量隔离(Sentinel默认采用):不创建线程池,而是计数器模式,记录业务使用的线程数量,达到信号量上限时,禁止新的请求

案例需求:给order-service服务中的UserClient的查询用户接口设置流控规则,线程数不能超过2然后利用Jmeter测试。

一次发送10个请求,有较大概率并发线程数超过2,而超出的请求会走之前定义的失败降级逻辑。

发现虽然结果是通过了,不过部分请求得到的响应是降级返回的null信息。


总结

线程隔离的两种手段是

  • 信号量隔离
  • 线程池隔离

信号量隔离的特点:

  • 基于计数器模式,简单,开销小

线程池隔离的特点:

  • 基于线程池模式,有额外开销,但隔离控制更强

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/454699.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构入门篇 之 【双链表】的实现讲解(附完整实现代码及顺序表与线性表的优缺点对比)

一日读书一日功&#xff0c;一日不读十日空 书中自有颜如玉&#xff0c;书中自有黄金屋 一、双链表 1、双链表的结构 2、双链表的实现 1&#xff09;、双向链表中节点的结构定义 2&#xff09;、初始化函数 LTInit 3&#xff09;、尾插函数 LTPushBack 4&#xff09;、头…

华为三层交换机:ACL的基本实验

实验要求&#xff1a; PC1不允许访问PC3&#xff0c;PC3可以访问PC1 分析问题&#xff1a; PC1不允许访问PC3&#xff0c;问题中含有“目标地址”则我们需要设置目标地址&#xff0c;这样基本ACL是不行的&#xff0c;必须使用高级ACL [sw1]acl ? INTEGER<2000-2999>…

数字图像处理 使用C#进行图像处理九 实现傅里叶变换

一、简述 傅立叶变换将图像分解为其正弦和余弦分量。换句话说,它将图像从空间域变换到频率域。这个想法是任何函数都可以用无限正弦函数和余弦函数之和来精确近似。傅里叶变换是实现此目的的一种方法。 网上有很多关于傅里叶变换的文章,这里就不进行赘述了,这里主要结合代码…

python爬虫实战——抖音

目录 1、分析主页作品列表标签结构 2、进入作品页前 判断作品是视频作品还是图文作品 3、进入视频作品页面&#xff0c;获取视频 4、进入图文作品页面&#xff0c;获取图片 5、完整参考代码 6、获取全部作品的一种方法 本文主要使用 selenium.webdriver&#xff08;Firef…

【WSN覆盖优化】基于改进黏菌算法的无线传感器网络覆盖 WSN覆盖优化【Matlab代码#65】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. 改进SMA算法1.1 改进参数p1.2 混沌精英突变策略 2. WSN节点感知模型3. 部分代码展示4. 仿真结果展示5. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取…

Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建

Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建 目录 Python 基于 OpenCV 视觉图像处理实战 之 开发环境搭建 一、简单介绍 二、该项目案例的开发环境 三、Python 环境搭建 1、Python 安装包下载 2、这里以 下载 Python 3.10.9 为例 3、安装 Python 3.10.9 4、检…

http协议-基于TCP的超文本传输协议

一、通过http最终实现一个效果 用我们自己电脑上的浏览器去访问我们自己写的python程序&#xff0c;这个程序就可以满足浏览器的需求&#xff0c;你可以从浏览器里面看到自己写出来的网页。所谓的协议就是一种规定。 二、http协议 正常情况下www.xxx是域名&#xff0c;将来…

前端实现复制粘贴功能

在前端开发的世界里&#xff0c;复制粘贴功能就像是那个总是被忽视&#xff0c;却在关键时刻能救你一命的老朋友。我们习惯了用那些古老的魔法咒语&#xff08;document.execCommand(copy)&#xff09;来实现这一功能&#xff0c;但时代在进步&#xff0c;技术在更新&#xff0…

LNMP架构之web服务器实战

LNMP架构 1.nginx部署 systemctl disable --now keepalived.service 关闭keepalived服务&#xff0c;避免冲突 将下载好的nginx软件压缩包直接拖入mobaxterm目录即可 tar zxf nginx-1.23.3.tar.gz cd nginx-1.23.3/ yum install -y gcc pcre-devel openssl-devel #安装依…

LInux系统架构----Nginx模块rewrite的规则与应用场景

LInux系统架构----Nginx模块rewrite的规则与应用场景 一.rewrite跳转实现 Nginx实现跳转通过ngx_http_rewrite_module模块支持URL重写、支持if条件判断&#xff0c;但是不支持else跳转时&#xff0c;循环最多可以执行10次&#xff0c;超过后nginx将返回500错误注&#xff1a;…

0基础使用dockerfile构建容器镜像

目录 一、使用dockerfile构建镜像 1.1、dockerfile指令 1.FROM 2.RUN 3.CMD 4.ENTRYPOINT 5.EXPOSR ​编辑 6.ADD和COPY ​编辑7.volume 8.USER 二、案例1&#xff1a;dockerfile构建httpd镜像 构建一个指定挂载点的httpd镜像 三、案例2&#xff1a;构建tomcat镜…

使用endnote插入引用文献导致word英文和数字变成符号的解决方案

使用endnote插入引用文献导致word英文和数字变成符号的解决方案 如图使用endnote插入引用文献导致word英文和数字变成符号字体Wingdings Wingdings 是一个符号字体系列&#xff0c;它将许多字母渲染成各式各样的符号&#xff0c;用途十分广泛。 **解决方法&#xff1a;**直接通…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时&#xff0c;几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法&#xff1a; 2. 错误的导入路径解决方法&#xff1a; 3. 第三方库的使用错误解决方法&#xff1a; 4. 包未正…

gpt-4-all模型中转实现

最近才完成这个功能&#xff0c;相信知道这个模型的人&#xff0c;应该已经熟悉了。这是我的中转&#xff1a;openai-api Chatbox配置如下&#xff1a; 模型测试&#xff1a; 1&#xff09;图片生成 2&#xff09;文件分析&#xff0c;链接读取&#xff1a;

WPF实时时间显示demo(MVVM)

跟着b站的视频学习做一个界面,它里面的时间不能实时刷新,因此自己研究写一个,同时加深一下自己对MVVM的理解. 运行结果: 实现步骤: 1.界面 界面设计就是放置了一个TextBlock,它的text绑定了ViewModel层里面的公告属性CurrentTime. <Grid><TextBlock Text"{Bindi…

【Vite+Ts】自动按需引入Element-Plus

安装插件 cnpm i -D unplugin-vue-components unplugin-auto-import unplugin-element-plus修改vite.config.ts // vite.config.ts import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; impor…

白嫖AWS云服务器,验证、注册指南

背景 不知道你想不想拥有一台属于自己的云服务器呢&#xff0c;拥有一台自己的云服务器可以建站&#xff0c;可以在上面搭建个人博客&#xff0c;今天我就来教大家如何申请亚马逊 AWS 免费云服务器&#xff0c;这个云服务器可以长达12个月的免费。而且到期后可以继续换个账号继…

【Flink SQL】Flink SQL 基础概念:SQL 动态表 连续查询

Flink SQL 基础概念&#xff1a;SQL 动态表 & 连续查询 1.SQL 应用于流处理的思路2.流批处理的异同点及将 SQL 应用于流处理核心解决的问题3.SQL 流处理的输入&#xff1a;输入流映射为 SQL 动态输入表4.SQL 流处理的计算&#xff1a;实时处理底层技术 - SQL 连续查询5.SQL…

Arduino IDE的下载和安装

一、Arduino的介绍 Arduino是一款开源电子原型平台&#xff0c;主要包含两部分&#xff1a;硬件&#xff08;各种型号的Arduino板&#xff09;和软件&#xff08;Arduino IDE&#xff09;。这个平台由意大利的Massimo Banzi、David Cuartielles等人共同开发设计&#xff0c;并于…

OPPO后端二面,凉了!

这篇文章的问题来源于一个读者之前分享的 OPPO 后端凉经&#xff0c;我对比较典型的一些问题进行了分类并给出了详细的参考答案。希望能对正在参加面试的朋友们能够有点帮助&#xff01; Java String 为什么是不可变的? public final class String implements java.io.Seri…