1、初识Sentinel
1.1雪崩问题
微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。
解决雪崩问题的常见方式有四种:
超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
流量控制:限制业务访问的QPS,避免服务因流量的突增而故障。
什么是雪崩问题?
• 微服务之间相互调用,因为调用链中的一个服务故障,引起整个链路都无法访问的情况。如何避免因瞬间高并发流量而导致服务故障?
• 流量控制如何避免因服务故障引起的雪崩问题?
• 超时处理• 线程隔离• 降级熔断
认识Sentinel
Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:home | Sentinel
Sentinel 具有以下特征:
• 丰富的应用场景 : Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。• 完备的实时监控 : Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。• 广泛的开源生态 : Sentinel 提供开箱即用的与其它开源框架 / 库的整合模块,例如与 Spring Cloud 、 Dubbo 、 gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel 。• 完善的 SPI 扩展点 : Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
1.2安装Sentinel控制台
E:\software\sentinel
java -jar -Dserver.port=8070 sentinel-dashboard-1.8.1.jar
用户名 密码:sentinel
如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:
尽量不修改用户名密码
1.3微服务整合Sentinel
(1)先引入sentinel依赖
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.aaa</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>product</artifactId>
<dependencies>
<dependency>
<groupId>com.aaa</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--nacos注册中心依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--eureka依赖-->
<!--<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>-->
<!--nacos-config配置中心依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--sentinel依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
<build>
<finalName>product</finalName>
</build>
</project>
(2)配置控制台地址:
浏览器访问
1.4簇点链路
簇点链路:就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每一个端点(Endpoint),因此SpringMVC的每一个端点(Endpoint)就是调用链路中的一个资源。
流控、熔断等都是针对簇点链路中的资源来设置的,因此我们可以点击对应资源后面的按钮来设置规则:
快速入门
点击资源/order/getInfo后面的流控按钮,就可以弹出表单。表单中可以添加流控规则,如下图所示:
其含义是限制 /order/getInfo这个资源的单机QPS为1,即每秒只允许1次请求,超出的请求会被拦截并报错
1.5流控模式
在添加限流规则时,点击高级选项,可以选择三种流控模式:
• 直接:统计当前资源的请求,触发阈值时对当前资源直接限流,也是默认的模式• 关联:统计与当前资源相关的另一个资源,触发阈值时,对当前资源限流• 链路:统计从指定链路访问到本资源的请求,触发阈值时,对指定链路限流
(1)流控模式-关联
配置流控规则,当/order/write资源被访问的QPS超过5时,对/order/read请求限流。
写操作被访问次数超过5时,对读操作限流
@GetMapping("write")
public String write(){
return "写操作~~~~";
}
@GetMapping("read")
public String read(){
return "读操作~~~~";
}
对谁限流,给谁加流控
使用压测工具
当/order/write资源被访问的QPS超过5时,对/order/read请求限流
(2)流控模式-链路
链路模式:只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值。
需求:有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流
步骤:
1. 在 OrderService 中添加一个 queryGoods 方法,不用实现业务2. 在 OrderController 中,改造 /order/query 端点,调用 OrderService 中的 queryGoods 方法3. 在 OrderController 中添加一个 /order/save 的端点,调用 OrderService 的 queryGoods 方法4. 给 queryGoods 设置限流规则,从 /order/query 进入 queryGoods 的方法限制 QPS 必须小于 2
1、service层
public String queryGood();
2、service 实现类
@Override
@SentinelResource("queryGood")//在其他层为其他方法标记为sentinel链路资源
public String queryGood() {
return "查询订单";
}
3、controller
@GetMapping("write")
public String write(){
orderService.queryGood();
return "写操作~~~~";
}
@GetMapping("read")
public String read(){
orderService.queryGood();
return "读操作~~~~";
}
1、Sentinel默认只标记Controller中的方法为资源,如果要标记其它方法,需要利用@SentinelResource注解,示例:
@SentinelResource("queryGood")//在其他层为其他方法标记为sentinel链路资源
2、Sentinel默认会将Controller方法做context整合,导致链路模式的流控失效,需要修改application.properties,添加配置:
#关闭上下文 spring.cloud.sentinel.web-context-unify=false
http://localhost:8090/order/write
http://localhost:8090/order/read
访问一下
流控模式有哪些?
直接:对当前资源限流
关联:高优先级资源触发阈值,对低优先级资源限流。
链路:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流