sentinel微服务限流

news/2024/12/26 0:42:01/文章来源:https://www.cnblogs.com/21CHS/p/18528825

sentinel(微服务限流)

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

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是由阿里巴巴开源的一款流量防护组件,Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

微服务的雪崩效应

概述:在微服务系统架构中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。一个服务的不可用导致整个系统的不可用的现象就被称之为雪崩效应。

image-20241022093811685

当服务D出现了问题了以后,调用服务D的服务A的线程就得不到及时的释放,在高并发情况下,随着时间的不断推移服务A的系统资源会被线程耗尽,最终导致服务A出现了问题,同理就会导致其他的服务也不能进行访问了

解决方案

超时处理

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

image-20241022094115993

隔离处理

隔离处理:将错误隔离在可控的范围之内,不要让其影响到其他的程序的运行。

熔断处理

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

流量控制

流量控制:限制业务访问的QPS(每秒的请求数),避免服务因流量的突增而故障。

image-20241022094233785

限流是一种预防措施,避免因瞬间高并发流量而导致服务故障,进而避免雪崩。其他的处理方式是一种补救措施,在部分服务故障时,将故障控制在一定范围,避免雪崩。

Sentinel 分为两个部分:

- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。

- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

sentinel入门

sentinel管理后台下载地址:https://github.com/alibaba/Sentinel/releases

image-20230624215112184

下载完毕以后就会得到一个jar包

image-20230624215403344

启动sentinel

  • 将jar包放到任意非中文目录,执行命令:
java -jar sentinel-dashboard-2.0.0-alpha-preview.jar
  • 如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:
配置项 默认值 说明
server.port 8080 服务端口
sentinel.dashboard.auth.username sentinel 默认用户名
sentinel.dashboard.auth.password sentinel 默认密码
  • 例如,修改端口:
java -Dserver.port=8090 -jar sentinel-dashboard-2.0.0-alpha-preview.jar

默认访问http://localhost:8080页面,就可以看到sentinel的控制台了

java整合sentinel

1、引入sentinel依赖

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

2、配置控制台

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

spring:cloud:sentinel:transport:dashboard: localhost:8080  # 配置sentinel控制台地址

3、访问spzx-cloud-user的任意接口

打开浏览器,访问http://localhost:10100/api/user/findUserByUserId/1,这样才能触发sentinel的监控。然后再访问sentinel的控制台,查看效果:

image-20241022105833117

流量控制

雪崩问题虽然有四种方案,但是限流是避免服务因突发的流量而发生故障,是对微服务雪崩问题的预防。

相关概念

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

资源:簇点链路中被监控的每一个接口就是一个资源,流控、熔断等都是针对簇点链路中的资源来设置的。

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

image-20241022145813561

我们可以点击对应资源后面的按钮来设置规则:

1、流控:流量控制

2、降级:降级熔断

3、热点:热点参数限流,是限流的一种

4、授权:请求的权限控制

快速入门

需求:给 /api/user/findUserByUserId/{userId}这个资源设置流控规则,QPS不能超过 5,然后测试。

步骤:

1、首先在sentinel控制台添加限流规则

image-20241022150033451

2、利用jmeter测试(模拟并发请求)

Apache JMeter 是 Apache 组织基于 Java 开发的压力测试工具,用于对软件做压力测试

下载地址:https://archive.apache.org/dist/jmeter/binaries/

通过如下命令打开jmeter

java -jar ApacheJMeter.jar

1、新建线程组

image-20241022150416064

2、配置参数==>10个线程,1秒内运行完,QPS是10,超过了5。

image-20241022150504942

3、添加HTTP请求:

image-20241022150545831

4、配置HTTP请求的参数:

image-20241022150721365

5、添加查看结果树,查看请求执行结果

image-20241022150839467

6、运行查看

image-20241022151000088

image-20241022151016551

注意:如果测试结果不是上述情况,那是因为sentinel在统计请求的时候,把一部分的请求统计到了下一秒中导致的。

流控模式

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

1、直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式

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

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

image-20241022151145542

关联模式

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

image-20241022184118103

语法说明:对/api/user/updateUserById资源的请求进行统计,当访问流量超过阈值时,就对/api/user/findUserByUserId/{userId}进行限流,避免影响/api/user/updateUserById资源。

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

案例实现:

1、在UserController新建一个端点:/api/user/updateUserById,无需实现业务

// 修改用户数据端点
@GetMapping(value = "/updateUserById")
public String updateUserById() {return "修改用户数据成功";
}

2、重启服务,访问对应的端点,让其产生簇点链路

image-20241022184516101

3、配置流控规则,当/api/user/updateUserById资源被访问的QPS超过5时,对/api/user/findUserByUserId/1请求限流。对哪个端点限流,就点击哪个端点后面的按钮。我们是对用户查询/api/user/findUserByUserId/1限流,因此点击它后面的按钮:

image-20241022184526181

我们在浏览器访问,可以发现:

image-20230628093300378

确实被限流了。

链路模式

链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值,如果超过阈值对从该链路请求进行限流。

配置方式:

1、/api/user/save --> users

2、/api/user/query --> users

如果只希望统计从/api/user/query进入到users的请求,并进行限流操作,则可以这样配置:

image-20241022184950720

案例实现:

1、在UserService中添加一个queryUsers方法,不用实现业务

public void queryUsers(){System.err.println("查询用户");
}

2、在UserController中,添加两个端点,在这两个端点中分别调用UserService中的queryUsers方法

@GetMapping(value = "/save")
public String save() {userService.queryUsers();System.out.println("保存用户");return "订单保存成功" ;
}@GetMapping(value = "/query")
public String query() {userService.queryUsers();System.out.println("查询用户");return "查询用户成功" ;
}

4、通过@SentinelResource标记UserService中的queryUsers方法为一个sentinel监控的资源(默认情况下,sentinel只监控controller方法)

@SentinelResource("users")
public void queryUsers(){System.err.println("查询用户");
}

5、更改application.yml文件中的sentinel配置

链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入spring mvc的所有请求设置同一个root资源,会导致链路模式失效。因此需要关闭这种资源整合。

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

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

image-20241022185451802

7、添加流控规则

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

image-20230628094433574

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

8、运行测试,察看结果树:

QPS为4,超过了我们设定的阈值2。

访问/api/user/save,没有进行限流

image-20230628094814795

访问/api/user/query,进行限流了

image-20230628094857374-168829026999536

流控效果

在流控的高级选项中,还有一个流控效果选项

image-20241022185854278

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

1、快速失败:达到阈值后,新的请求会被立即拒绝并抛出FlowException异常,是默认的处理方式

2、warm up:预热模式,对超出阈值的请求同样是拒绝并抛出异常,但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值

3、排队等待:让所有的请求按照先后次序进入到一个队列中进行排队,当某一个请求最大的预期等待时间超过了所设定的超时时间时同样是拒绝并抛出异常

warm up

阈值一般是一个微服务能承担的最大QPS,但是一个服务刚刚启动时,一切资源尚未初始化(冷启动),如果直接将QPS跑到最大值,可能导致服务瞬间宕机。

warm up也叫预热模式,是应对服务冷启动的一种方案。阈值会动态变化,从一个较小值逐渐增加到最大阈值。

工作特点:请求阈值初始值是 maxThreshold / coldFactor, 持续指定时长(预热时间)后,逐渐提高到maxThreshold值,而coldFactor的默认值是3。

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

image-20241022185939179

案例需求:给/api/user/findUserByUserId/{userId}这个资源设置限流,最大QPS为10,利用warm up效果,预热时长为5秒

配置流控规则

image-20230628095505037

排队等待

排队等待:让所有的请求按照先后次序进入到一个队列中进行排队,当某一个请求最大的预期等待时间超过了所设定的超时时间时同样是拒绝并抛出异常

例如:QPS = 5,意味着每200ms处理一个队列中的请求;timeout = 2000,意味着预期等待时长超过2000ms的请求会被拒绝并抛出异常。

那什么叫做预期等待时长呢?

比如现在一下子来了12 个请求,因为每200ms执行一个请求,那么:

1、第6个请求的预期等待时长 = 200 * (6 - 1) = 1000ms

2、第12个请求的预期等待时长 = 200 * (12-1) = 2200ms

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

image-20230628100019712-168829026999544

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

image-20230628100049968

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

案例需求:给/api/user/findUserByUserId/{userId}这个资源设置限流,最大QPS为10,利用排队的流控效果,超时时长设置为5s

添加流控规则

image-20241022190737263

熔断规则

熔断分为两种情况

1、当目标接口的响应时间较差(慢调用的比例、数量超过阈值),2、基于异常比例、异常数量

响应时间比例

image-20241022191349400

当对指定的资源接口进行访问时,1秒(统计时长)内至少5个请求(最小请求数)。

其中80%(比例阈值)的请求对应响应时间超过800ms(最大RT,response time),此时就开始熔断,熔断的时间1Os(熔断时长)。

在被熔断的期间,是不允许访问目标接口,此时可以指定降级方案(兜底方法,返回固定的结果)

当熔断时长到达后(时间到了),放行一个请求去访问目标接口,如果此时RT(响应)时间依然超过800s(最大RT),此时就继续熔断(10s);如果放行的一个请求,响应时间没有超过800s(最大RT),则熔断结束;接下来开始进行下一轮的统计。

注意:熔断规则和流量控制的链路模式不能一起使用

异常比例

image-20241022192044518

1s之内,至少5个请求,其中80%的请求抛出异常,此时熔断就开启。熔断时长10s到达之后,此时熔断器变成”半开启"状态。放行一个请求,如果这个请求依然抛出异常,此时就继续熔断。否则熔断关闭。

热点参数限流

热点参数限流是分别统计参数值不相同的请求,判断是否超过QPS阈值,同一个资源接口,针对不同的参数指,执行不同的QPS阈值。

例:userid=1为普通VIP用户,此时对该资源接口的调用每秒最多只允许调用5次。userid=3为超级VIP用户,每秒对该资源接口的访问可以访问8次。其他的普通用户,每秒只允许访问2次。

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

实现步骤:

1、标记资源

给UserController中的/api/user/findUserByUserId/{userId}资源添加注解:

@SentinelResource("hot")  // 声明资源名称
@GetMapping(value = "/findUserByUserId/{userId}")
public User findUserByUserId(@PathVariable(value = "userId") Long userId ,@RequestHeader(name = "Truth" , required = false)String header) {log.info("UserController...findUserByUserId方法执行了... ,header: {} , dateformat: {} " , header , patternProperties.getDateformat());return userService.findUserByUserId(userId) ;
}

2、热点参数限流规则

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

image-20241022193019498

image-20241022193039477

@SentinelResource注解

@SentinelResource 是一个用于在 Java 应用程序中标记限流、熔断和降级资源的注解,由 Alibaba 开发的 Sentinel 库提供。这个注解广泛应用于微服务架构中,用于增强应用的容错能力和流量控制能力。

主要功能和使用方式

  1. 资源定义: 使用 @SentinelResource 注解的方法会被定义为一个 Sentinel 资源,Sentinel 将会监控该资源的流量

  2. 参数:

    • value: 定义资源的名称,通常与方法名称相同,但也可以自定义。
    • blockHandler: 指定一个方法,该方法用于处理被限流时的请求。这个方法应具有相同的参数类型,如限流、降级触发等情况发生时,可以调用该方法进行处理。
    • fallback: 指定一个方法,该方法将在原方法出现异常时调用。这个方法通常用于处理业务逻辑中的异常。
  3. 使用示例:

    import com.alibaba.csp.sentinel.annotation.SentinelResource;  
    import org.springframework.web.bind.annotation.GetMapping;  
    import org.springframework.web.bind.annotation.RestController;  @RestController  
    public class MyController {  @GetMapping("/someApi")  @SentinelResource(value = "someApi", blockHandler = "handleBlock", fallback = "handleFallback")  public String someApi() {  // 你的业务逻辑  return "Hello, Sentinel!";  }  // 业务接口被限流、或降级时触发改方法public String handleBlock() {  return "Request has been blocked!";  }  // 业务接口出现异常时触发改方法public String handleFallback() {  return "An error occurred, please try again!";  }  
    }
    
    • blockHandlerClass:用于指定处理被限流或被阻塞请求的处理类。通过这个属性,可以将处理逻辑分离到一个特定的类中,从而使代码更加模块化和可维护。
    import com.alibaba.csp.sentinel.annotation.SentinelResource;  
    import org.springframework.web.bind.annotation.GetMapping;  
    import org.springframework.web.bind.annotation.RestController;  @RestController  
    public class MyController {  @GetMapping("/test")  @SentinelResource(value = "testResource",   blockHandlerClass = BlockHandlerClass.class,   blockHandler = "handleBlock")  public String test() {  return "Hello, Sentinel!";  }  
    }  class BlockHandlerClass {  // 处理被限流的请求  public static String handleBlock() {  return "Request has been rate-limited!";  }  
    }
    

使用场景

  • 流量控制: 在高流量情况下,通过设置阈值控制请求数量,避免服务过载。
  • 熔断和降级: 当某个服务出现异常或超时,可以触发降级措施以保护系统的整体稳定性。
  • 监控与告警: 集成后可以实时监控请求情况,并可以配置相关告警策略

规则持久化

流控规则,热点呗则,熔断规则都可以进行持久化。

流量规则持久化

(1)在nacos配置中心,上传配置文件

image-20241022213030197

2、在需要使用持久化规则的微服务上添加依赖

<!--sentinel对应的规则持久化,是基于nacos进行存储的-->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

3、在该微服务上配置相关参数:

image-20241022213310570

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ工作模式

RabbitMQ工作模式RabbitMQ提供了多种工作模式:简单模式,work模式 ,Publish/Subscribe发布与订阅模式,Routing路由模式,Topics主题模式等官网对应模式介绍:https://www.rabbitmq.com/getstarted.html 1、简单模式 生产者直接发送消息到队列上(虽然没有指明使用交换机,但是…

RabbitMQ消息幂等性保障

消息幂等性保障幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。在MQ中指,消费多条相同的消息,得到与消费该消息一次相同的结果消息幂等性保障 乐观锁机制 @Component public class …

WPF Button控件 这里可以点一下

WPF Button控件 这里可以点一下button表示一个 Windows 按钮控件,该控件对 Click 事件做出反应。 可以点一下button,执行程序操作,如:显示对话框,更改显示内容。 button的content属性表示按钮上显示的文字。<StackPanel><!-- 一个按钮控件,太小了,根本就看不到…

WPF Textbox控件 这里可以输入文字

WPF Textbox控件 这里可以输入文字 textbox控件,用于输入文字。如网页上输入账号密码的地方就是文本框。 文本框的text属性可以提示文字,只能包含无格式文本。

蛋白粉?蛋白质

蛋白粉不能用开水冲,但我们摄入的蛋白质却大都经过了烹煮。 为什么蛋白质不怕开水,而蛋白粉怕开水? 这似乎是矛盾的,其实不然。 问题是,很多人并不了解蛋白质的分子结构,不了解蛋白粉的溶解原理。 如果不了解其中的原理,很容易给出错误的解释。咳咳咳~~干货内容一次可…

【考试题解】多校A层冲刺NOIP2024模拟赛18

目录A. 选彩笔(rgb)题目内容部分分正解思路代码B. 兵蚁排序(sort)题目内容部分分75pts正解思路代码C. 人口局DBA(dba)题目内容部分分60pts正解思路代码D. 银行的源起(banking) A. 选彩笔(rgb) 题目内容 有 \(N\) 支彩笔,每支彩笔有 \(R_i,G_i,B_i\) 三个属性。定义两只彩笔 \(…

学习笔记(二十五):ArkUi-栅格布局 (GridRow/GridCol)

概述: 栅格布局是一种通用的辅助定位工具,对移动设备的界面设计有较好的借鉴作用。主要优势包括:提供可循的规律:栅格布局可以为布局提供规律性的结构,解决多尺寸多设备的动态布局问题。通过将页面划分为等宽的列数和行数,可以方便地对页面元素进行定位和排版。统一的定位…

WPF TextBlock控件 显示两段文字

WPF TextBlock控件 显示两段文字 TextBlock控件不止显示两段文字,可显示多行。<StackPanel><!-- 显示多行,LineBreak表示换行 --><TextBlock>盼望着,<LineBreak />盼望着,<LineBreak />东风来了,春天的脚步近了。</TextBlock><!-…

运筹学两阶段法中的人工变量数量问题

运筹学两阶段法中的人工变量数量问题 在运筹学的两阶段法中,为了找到线性规划(LP)问题初始解的可行性,通常需要在约束条件中引入人工变量。以下是我学习课本后对相关内容的总结。1. 人工变量的引入条件等式约束(=):每一个等式约束需要引入一个人工变量。大于等于约束(≥…

第三十四讲:join语句怎么优化?

第三十四讲:join语句怎么优化? 简概:万年不变的开头 ​ 在上一篇文章中,我和你介绍了 join 语句的两种算法,分别是 Index Nested-Loop Join(NLJ) 和 Block Nested-Loop Join(BNL)。我们发现在使用 NLJ 算法的时候,其实效果还是不错的,比通过应用层拆分成多个语句然后再拼…

Cursor使用

Cursor是一款AI 代码编辑器,官网地址为https://www.cursor.com/,直接在官网下载安装即可,基于VS Code二次开发而来,之所以没有采用插件方式,在官方网站上给出的答案是某些功能插件无法实现,产品专注在使用AI来进行编程方面,价格方面还不便宜,Pro单月20刀,企业版单月单…