【SpringCloud】使用 Spring Cloud Alibaba 之 Sentinel 实现微服务的限流、降级、熔断

目录

    • 一、Sentinel 介绍
      • 1.1 什么是 Sentinel
      • 1.2 Sentinel 特性
      • 1.3 限流、降级与熔断的区别
    • 二、实战演示
      • 2.1 下载启动 Sentinel 控制台
      • 2.2 后端微服务接入 Sentinel 控制台
        • 2.2.1 引入 Sentinel 依赖
        • 2.2.2 添加 Sentinel 连接配置
      • 2.3 使用 Sentinel 进行流控(含限流)
        • 2.3.1 对接口添加 Sentinel 资源标记
        • 2.3.2 Sentinel 的流控模式
        • 2.3.3 Sentinel 的流控效果
        • 2.3.4 直接流控演示
        • 2.3.5 关联流控演示
        • 2.3.6 根据调用源对接口限流
          • 1. 给请求打标
          • 2. 解析请求源
          • 3. 下发限流规则
      • 2.4 使用 Sentinel 实现降级、熔断
        • 2.4.1 Sentinel 中的熔断策略
        • 2.4.2 实现降级、熔断
          • 1. 核心思路
          • 2. 降级实现
          • 3. 熔断策略

一、Sentinel 介绍

1.1 什么是 Sentinel

  • Sentinel 对开发者的大概印象应该是阿里开源的一个SpringCloud 组件,用来做微服务的限流、降级和熔断。这也是本文从概念和实战上主要的展开点。
  • 官方点的话说就是: Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。

在这里插入图片描述

1.2 Sentinel 特性

官方总结了 Sentinel 组件的4大特性,概括了 Sentinel 组件提供的能力:

  • 丰富的应用场景:阿里巴巴 10 年双十一积累的丰富流量场景,包括秒杀、双十一零点持续洪峰、热点商品探测、预热、消息队列削峰填谷等多样化的场景;
  • 易于使用,快速接入:简单易用,开源生态广泛,针对 Dubbo、Spring Cloud、gRPC、Zuul、Reactor、Quarkus 等框架只需要引入适配模块即可快速接入;
  • 多样化的流量控制:资源粒度、调用关系、指标类型、控制效果等多维度的流量控制;
  • 可视化的监控和规则管理:简单易用的 Sentinel 控制台;

Sentinel特性概览

1.3 限流、降级与熔断的区别

  • 限流是在流量进入到系统内之前,先进行一个统计计算,如果已经超过设定的阈值,则直接拒绝当前的请求,那么当前流量不会进入服务的内部;
  • 降级指的是如果在执行一个请求的调用时,如果发生了异常,那么请求就会继续执行指定的降级逻辑。此时,请求已经进入到了服务内部;
  • 熔断是对一个时间窗口内处理的请求的结果进行统计后,如果这批请求的错误率达到了阈值(或者慢接口比例达到了阈值),则会触发一个指定时间段长度的熔断;
    服务的限流、降级、熔断这三板斧的结合在很大程度上抑制了服务雪崩的发生。

二、实战演示

2.1 下载启动 Sentinel 控制台

我们到 Sentinel 官方的 Github 上下载 sentinel-dashboard 服务的 Jar 包,Sentinel 服务的限流、熔断等规则的下发就是通过 sentinel-dashboard 来进行的,下载链接。当前的最新版本是1.8.7。

在这里插入图片描述
sentinel-dashboard 的 Jar 包下载完毕后,把它放在合适的目录,使用如下命令启动Jar包:

java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=localhost:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.7.jar

然后在浏览器的地址框内输入 http://localhost:8888/ 会进入 Sentinel 控制台的登陆界面:

在这里插入图片描述

默认的用户名和密码都是 sentinel,输入后即可进入 Sentinel 控制台主界面:

在这里插入图片描述

2.2 后端微服务接入 Sentinel 控制台

2.2.1 引入 Sentinel 依赖

在我们需要使用 Sentinel 组件的后端微服务中先引入 Sentinel 的依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.2.2 添加 Sentinel 连接配置

如果要想将后端微服务对接到 Sentinel 控制台,除了要添加 Sentinel 依赖以外,还需要在配置文件中添加上 Sentinel 控制台相关的配置信息,主要是为了配置Sentinel 控制台的访问地址,此处配置的本地访问端口号为8888。

spring:
  cloud:
    sentinel:
      transport:
        # sentinel 的默认端口号为 8719
        port: 8719
        # dashboard地址
        dashboard: localhost:8888

2.3 使用 Sentinel 进行流控(含限流)

2.3.1 对接口添加 Sentinel 资源标记

对于 Sentinel 组件来说,一切的 API 接口都是资源,Sentinel 的职责就是在流量到来时,根据这些 Sentinel 资源的负载情况对流量进行管理。所以,我们需要先对代码中定义的 API 接口打上 Sentinel 资源的标记。Sentinel 是通过 @SentinelResource 注解对 API 接口打标记的。下面以2个获取商品的接口为例演示下用法。

	@GetMapping("/getGoods")
    @SentinelResource(value = "getGoods")
    public CoinGoodsInfo getGoods(@RequestParam("id") Long id){
        log.info("Get goods, id={}", id);
        return coinGoodsService.getGoodsInfo(id);
    }

    // 批量获取
    @GetMapping("/getBatch")
    @SentinelResource(value = "getGoodsInBatch")
    public Map<Long, CoinGoodsInfo> getGoodsInBatch(@RequestParam("ids") Collection<Long> ids) {
        log.info("getGoodsInBatch: {}", JSON.toJSONString(ids));
        return coinGoodsService.getGoodsInfoMap(ids);
    }
2.3.2 Sentinel 的流控模式

在使用 Sentinel 演示具体的流控之前,先简单的介绍下 Sentinel 的流控。Sentinel 的进行流量控制时分为3种模式:直接流控,关联流控,链路流控。

  • 直接流控:进行流量管理时直接作用于目标 Sentinel 资源,如果当前的访问压力大于预先设定的阈值,直接拦截当前的请求;
  • 关联流控:在关联流控中,Sentinel 资源中存在一个优先级的概念,同时他们会共享某个资源,比如都依赖某个接口或者共享一个数据库连接池。当高优先级的 Sentinel 资源的访问流量达到了设定阈值时,会对低优先级的 Sentinel 资源接口进行限流。
  • 链路流控:当指定链路上的访问量大于某个阈值时,对当前资源进行限流。
2.3.3 Sentinel 的流控效果

Sentinel 目前提供了 3 种流控效果,分别是:快速失败,Warm-up,排队等待。

  • 快速失败:当某个 Sentinel 资源的访问流量超过了设定的阈值, 后面的请求会直接被拦截住;
  • Warm-up:该模式下系统承载的流量有一个缓慢拉高的过程,而不是一开始就将系统承载的流量设置为最高可承受的流量。假设我们设置的系统QPS阈值是100,预热时间为5秒,那么 Sentinel 会在 5 秒内逐渐的将限流阈值从33 拉高到 100。因为 Sentinel 内部有一个冷加载因子,取值为3。100/3=33。因此初始的限流阈值为33。
  • 排队等待:如果当前的流量已经超过了接口设定的阈值,超出部分的请求会被放到队列中,等到系统的请求量下来,再将请求交给系统处理。同时,注意被放入到队列的请求有一个超时等待时间,如果被放入到队列的请求在队列中滞留的时间过长,该请求会被丢弃。
2.3.4 直接流控演示

首先,我们需要在代码中先指定请求被限流时,要执行的限流逻辑。该限流部分的逻辑指定,需要我们先定义对应的降级方法,然后在 @SentinelResource 注解中的 blockHandler 属性绑定降级方法的方法名即可。

	@GetMapping("/getGoods")
    @SentinelResource(value = "getGoods", blockHandler = "getGoods_block")
    public CoinGoodsInfo getGoods(@RequestParam("id") Long id){
        log.info("Get goods, id={}", id);
        return coinGoodsService.getGoodsInfo(id);
    }
    
	public CoinGoodsInfo getGoods_block(Long id){
        log.info("Calling limited, id={}", id);
        return null;
    }

    // 批量获取
    @GetMapping("/getBatch")
    @SentinelResource(value = "getGoodsInBatch",
            fallback = "getGoodsInBatch_fallback",
            blockHandler = "getGoodsInBatch_block")
    public Map<Long, CoinGoodsInfo> getGoodsInBatch(@RequestParam("ids") Collection<Long> ids) {
        log.info("getGoodsInBatch: {}", JSON.toJSONString(ids));
        return coinGoodsService.getGoodsInfoMap(ids);
    }

如上的 /getGoods 接口,该接口因限流调用失败时,会执行 blockHandler 属性绑定的 getGoods_block 方法,返回 null

下面我们在代码中演示下直接流控。直接流控的配置如下图:

在这里插入图片描述

资源名:就是我们使用 @SentinelResource 注解时,value 属性指定的值。
阈值类型:选QPS,表示请求的QPS(Query per second),这里我们设置的阈值为1。
流控模式:选“直接”
流控效果:可以选“快速失败”,也可以选择其他选项,“快速失败”简单直接,用postman 等工具测试时可以直接看到效果。

点击“新增”,这条流控规则就新增完毕了。

在 postman 中调用相应的接口,点的快一点,保证1秒内超过1次,可以看到打印的日志,确实是走了限流逻辑的。

在这里插入图片描述

2.3.5 关联流控演示

接下来我们还是利用在 2.3.4 中的代码实现。假设2个接口/getGoods/getBatch 存在资源竞争关系,然后我们在 Sentinel 控制台中配置关联流控的规则,其具体的配置项如下图:

在这里插入图片描述
这里设置流控规则时,设置的资源名为 getGoodsInBatch ,关联到的sentinel资源是getGoods ,设置的 QPS=1。意思就是 Sentinel 资源 getGoods (/getGoods 接口)的访问QPS为1时,就会触发对 Sentinel 资源getGoodsInBatch/getBatch 接口)的限流。

2.3.6 根据调用源对接口限流

背景:这种情况就是,假设有3个微服务A,B,C,微服务A,B 都依赖微服务C,都需要调用微服务C 的接口。而且对于A, B 这2个微服务来说,A 是核心业务,B 是边缘业务。现在我们在使用Sentinel 对微服务 C 中的某接口进行限流时,需要识别这个请求是来自微服务A 还是 B。在业务的高峰期,我们需要对来自微服务B 的请求进行限流。

核心思路主要分为3个步骤:

  1. 服务消费者在下发请求时,对请求打标,表明请求来源。在微服务内使用拦截器,对所有的请求加上统一的header即可;
  2. 服务提供者在处理请求是需要处理Request,识别Request 来源。实现 Sentinel 提供的 RequestOriginParser 接口,获取Request中的请求源标记;
  3. 在下发限流规则时需要指定请求源服务注册发现时上报的服务名,并配置其它的限流规则;

下面我们来一一实现。

1. 给请求打标

因为我微服务间调用使用的是 Feign,所以这里我实现 FeignRequestInterceptor 接口完成一个拦截器,为所有的请求统一加上 Header。

@Configuration
public class SentinelInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("SentinelSource", "coin-customer-src");
    }
}
2. 解析请求源

实现 Sentinel 提供的 RequestOriginParser 接口,获取Request中的请求源标记。

@Component
public class SentinelOriginParser implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        return request.getHeader("SentinelSource");
    }
}
3. 下发限流规则

下发新的限流规则,针对来源不再是default 变成了 microservice-A ,这意味着当请求流量达到设定阈值时,限流的拦截只对该微服务生效。
在这里插入图片描述

2.4 使用 Sentinel 实现降级、熔断

2.4.1 Sentinel 中的熔断策略

Sentinel 中有3种熔断策略指标:慢调用比例,异常比例,异常数。

  1. 慢调用比例:该场景下会统计每个调用的RT(Response Time),是否会超过设定的阈值,在统计的时间窗口内如果慢调用的比例超过了阈值,则会进行熔断;
  2. 异常比例:选择了异常比例策略,Sentinel 会统计每个接口调用发生异常的情况,如果,如果调用发生异常的情况占总调用的比例超过设定阈值,就会触发熔断;
  3. 异常数:就是会计算当前时间窗口内所有接口调用的异常情况,如果调用失败次数超过了设定的阈值,就会触发熔断;
2.4.2 实现降级、熔断
1. 核心思路

因为我们在选定了熔断策略之后,当服务触发了熔断,熔断期间,接口就会走降级策略。所以,首先,需要在代码中实现降级逻辑;其次,需要在 Sentinel 控制台添加熔断策略。

2. 降级实现

接下来我们在2个接口的 @SentinelResource 注解中,使用 fallback 属性绑定我们实现了降级逻辑的降级方法。

	@GetMapping("/getGoods")
    @SentinelResource(value = "getGoods", fallback="getGoods_fallback", blockHandler = "getGoods_block")
    public CoinGoodsInfo getGoods(@RequestParam("id") Long id){
        log.info("Get goods, id={}", id);
        return coinGoodsService.getGoodsInfo(id);
    }
    
	public CoinGoodsInfo getGoods_block(Long id){
        log.info("Calling limited, id={}", id);
        return null;
    }
    
	public CoinGoodsInfo getGoods_fallback(Long id) {
        log.info("Calling fallback, id={}", id);
        return null;
    }

    // 批量
    @GetMapping("/getBatch")
    @SentinelResource(value = "getGoodsInBatch",
            fallback = "getGoodsInBatch_fallback",
            blockHandler = "getGoodsInBatch_block")
    public Map<Long, CoinGoodsInfo> getGoodsInBatch(@RequestParam("ids") Collection<Long> ids) {
        log.info("getGoodsInBatch: {}", JSON.toJSONString(ids));
        return coinGoodsService.getGoodsInfoMap(ids);
    }

	public Map<Long, CoinGoodsInfo> getGoodsInBatch_fallback(Collection<Long> ids) {
        log.info("Calling fallback, ids={}", ids.toString());
        return new HashMap<>();
    }

    public Map<Long, CoinGoodsInfo> getGoodsInBatch_block(
            Collection<Long> ids, BlockException exception) {
        log.info("calling is limited, ids: {}, exception: ", ids, exception);
        return new HashMap<>();
    }
3. 熔断策略

我们在 Sentinel 控制台中添加熔断规则如下,对 Sentinel 资源 getGoods 添加熔断规则,熔断策略选择“异常比例”,设置的比例阈值为 0.4 ,熔断时长为10秒,最小请求数为50,统计时长为10000毫秒。结合起来就是在 10000毫秒的时间窗口内统计所有的请求,当时间窗内的请求数大于50个,且请求失败率大于40%时,会触发一个10秒的熔断。 熔断期间会执行我们代码中定义的降级逻辑。

在这里插入图片描述

启动服务,调用/getGoods 接口,可以看到确实是走了降级逻辑的。

在这里插入图片描述

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

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

相关文章

【SAP Hana】SAP S/4 HANA 数据库底表查询及运维管理

1、SAP S/4 HANA 简介 1.1 S4与ECC的区别 SAP ECC时期支持常规主流的关系型数据库&#xff0c;如MSSQL、ORACLE、IBM DB2等。 SAP S4 仅支持在HANA数据库上运行。 SAP基于HANA的内存计算、列式存储&#xff0c;以及并行计算特性&#xff0c;对SAP数据底表做了大量的改造优化&am…

java.lang.IllegalStateException: Promise already completed.

spark submit 提交作业的时候提示Promise already complete 完整日志如下 File "/data5/hadoop/yarn/local/usercache/processuser/appcache/application_1706192609294_136972/container_e41_1706192609294_136972_02_000001/py4j-0.10.6-src.zip/py4j/protocol.py"…

【2024软件测试面试必会技能】Jmeter_性能测试(5):负载测试和压力测试

负载测试 负载测试/容量测试&#xff1a;通过在测试过程中不断的调整负载&#xff0c;找到在多少用户量情况下&#xff0c;系统出现性能下降拐点&#xff1b;也被称为容量测试&#xff1b; 举例&#xff1a; 微信发送红包的负载测试&#xff1a; 1、找运维人员了解目前系统…

多普勒明渠流量监测系统

TH-ML1随着科技的不断进步&#xff0c;多普勒明渠流量监测系统作为一种先进的流量测量技术&#xff0c;正逐渐在水利、环保、农业等领域展现出其强大的应用潜力。 一、多普勒明渠流量监测系统的基本原理 多普勒明渠流量监测系统基于多普勒效应进行流量测量。多普勒效应是指当波…

C#,数值计算,矩阵的乔莱斯基分解(Cholesky decomposition)算法与源代码

一、安德烈路易斯乔尔斯基 安德烈路易斯乔尔斯基出生于法国波尔多以北的查伦特斯海域的蒙古扬。他在波尔多参加了Lyce e&#xff0c;并于1892年11月14日获得学士学位的第一部分&#xff0c;于1893年7月24日获得第二部分。1895年10月15日&#xff0c;乔尔斯基进入莱科尔理工学院…

SQL Server ID 自增不连续、删除数据后再次插入ID不连续

背景 当我们使用SQL Server 进行数据库操作时&#xff0c;经常会把 Table 的 ID 设置成主键自增 PRIMARY KEY IDENTITY&#xff0c;但是这样做存在一个问题就是 当我们删除一行数据后&#xff0c;再次添加后会看到ID的顺序不连续&#xff0c;如下所示。 查询一下&#xff1a;…

4.pom文件介绍Maven常用命令

1.pom.xml文件介绍. 1.1project标签和modelVersion标签介绍. pom.xml文件是maven的核心文件&#xff0c;POM(Project Object Model&#xff0c;项目对象模型)定义了项目的基本信息&#xff0c;用于描述如何构建&#xff0c;声明项目依赖;&#xff1b; 1.2依赖坐标介绍. 依赖的…

Springboot集成Druid实现监控功能

Druid是阿里巴巴开发的号称为监控而生的数据库连接池&#xff0c;在功能、性能、扩展性方面&#xff0c;都超过其他数据库连接池&#xff0c;包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource等等等&#xff0c;秒杀一切。Druid可以很好的监控DB池连接和SQL的执行情况&#…

STM32G030C8T6:定时器1ms中断(以64MHz外部晶振为例)

本专栏记录STM32开发各个功能的详细过程&#xff0c;方便自己后续查看&#xff0c;当然也供正在入门STM32单片机的兄弟们参考&#xff1b; 本小节的目标是&#xff0c;系统主频64 MHZ,采用高速外部晶振&#xff0c;通过定时器3 每秒中断控制 PB9 引脚输出高低电平&#xff0c;从…

【服务器】服务器推荐

一、引言 在数字世界的浪潮中&#xff0c;服务器作为数据存储和处理的基石&#xff0c;其重要性不言而喻。而在这个繁星点点的市场中&#xff0c;雨云以其独特的优势和超高的性价比&#xff0c;逐渐成为众多企业和个人的首选。今天&#xff0c;就让我带你走进雨云的世界&#…

DC与DCT DCG的区别

先进工艺不再wire load model进行静态时序分析&#xff0c;否则综合结果与后端物理电路差距很大&#xff0c;因此DC综合工具也进行了多次迭代&#xff0c;DC工具有两种模式&#xff0c;包括wire load mode和Topographical Mode&#xff0c;也就是对应的DC Expert和DC Ultra。 …

ios抓包Tunnel to......443

fiddler官网下载“CertMaker for iOS and Android”插件&#xff0c;官网插件&#xff1a;https://www.telerik.com/fiddler/add-ons 双击运行插件后&#xff0c;重启fiddler&#xff0c;ios重新安装证书即可

K8S部署Java项目 pod的logs报错为:Error: Unable to access jarfile app.jar

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

psp游戏存档收集SAVEDATA

不想从头开始 ppsspp存档目录 pc&#xff1a;ppsspp解压目录\memstick\PSP\SAVEDATA 安卓&#xff1a;根目录\PSP\SAVEDATA 噬神者2(日版) NPJH50832099c645531020001000 風燐-https://wwl.lanzouq.com/iI1R01owozxa 咲夜-https://wwl.lanzouq.com/id1tX1owp2uf につてのぬ…

【ACW 服务端】页面操作Java增删改查代码生成

版本: 1.2.2-JDK17-SNAPSHOT 项目地址&#xff1a;wu-smart-acw 演示地址&#xff1a;演示地址 admin/admin Java增删改查代码生成 找到对应菜单 选择你需要的数据实例 选择数据库 选择数据库表 选择客户端&#xff08;如果是本地ACW服务代码启动默认注册上的客户端ID是…

AD9226 65M采样 模数转换

用 vivado 写的 AD9220_ReadTEST module AD9220_ReadTEST( input clk, input rstn,output clk_driver, //模块时钟管脚 input [12:0]IO_data, //模块数据管脚output [11:0]ADC_Data,//12位ADC数据 output ADC_OTR //信号过压标志位 );wire areset, pll260m_lockedPIN; wire…

开源分子对接程序rDock的安装及使用流程

前言 本文介绍开源分子对接程序rDock在Linux Ubuntu 22.04系统上的conda安装、编译安装过程及程序使用流程。 一、rDock是什么&#xff1f; rDock来源 rDock是一个快速、多功能的开源对接程序&#xff0c;可用于将小分子与蛋白质和核酸对接。它专为高通量虚拟筛选&#xff08…

OLED透明屏厂家:开启2024年新征程

随着科技的不断进步和创新&#xff0c;OLED透明屏作为一种前沿的显示技术&#xff0c;正逐渐走进人们的视野&#xff0c;成为多个领域的焦点。在2024年2月21日这个特殊的日子&#xff0c;我们这家领先的OLED透明屏厂家正式开工&#xff0c;预示着我们将迎来一个充满机遇和挑战的…

Ubuntu22部署MySQL5.7详细教程

Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL检查状态登录MySQL 四、开启远程访问功能1、允许其他主机通过root访问数据库2、修改配置文件&#xff0c;允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下&#xff0c;Ubuntu2…

穿越科技的电影之旅:计算机专业必看的三部经典电影

文章目录 方向一&#xff1a;电影推荐方向二&#xff1a;技术与主题方向三&#xff1a;职业与人生 计算机专业必看的几部电影&#xff0c;就像一场精彩的编程盛宴&#xff01;《黑客帝国》让你穿越虚拟世界&#xff0c;感受高科技的魅力&#xff1b;《社交网络》揭示了互联网巨…