sentinel是什么
就是一个框架可以控制流量,保证服务的稳定性,还提供了一个前台页面来监控配置.
分为两个部分:
核心库: java客户端,不依赖任何框架,就是放在我们代码里面跑的.
控制台: 用于监控服务,做配置的页面
控制台使用
- 前台监控页面下载地址.
- 下载好直接java -jar就可以运行, 默认端口 8080 账号密码都是 sentinel
- 创建sentinel客户端,
引入 pom文件
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
yml 配置文件
server:
port: 8081
spring:
application:
name: provider-01
cloud:
# 注册中心配置信息
nacos:
discovery:
server-addr: localhost:8848
# sentinel配置信息
sentinel:
transport:
dashboard: localhost:8080
port: 8719
management:
endpoint:
web:
exposure:
include: "*"
- 启动后
因为sentinel是懒加载,所以要先请求一次服务
,查看sentinel控制台信息
sentinel 控制台操作
流控规则
-
资源名: 唯一名称,默认请求路径
-
针对来源: sentinel可以针对调用者进行限流,
填写微服务名,默认default
针对QPS 的限制 -
阈值类型: QPS/线程数
添加了之后如果一秒内多次请求/test01 接口,则会返回失败. -
流控模式:
直接
: 当api打到限流条件时,直接限流
关联
: 当关联的资源达到阈值时,就限流自己
当 /test02 QPS 超过 1 的时候 /test01 访问失败
链路
: 只记录指定链路上的流量
流控效果
- 快速失败: 就是直接返回失败
- 预热: 默认冷因子为3.代表一开始只接受 最大值/3 的 QPS,等待10秒之后才能让QPS达到30
- 排队等待: 让请求匀速通过,阈值一定要设置成QPS否则无效.应用场景为一段时间内大量请求打过来,然后一段时间又没有请求,再一段时间又有大量请求,阶段性的高并发,就把请求均匀的排队
降级规则
-
慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
20个请求里面如果百分50的请求都超过2000毫秒才返回,整个接口就熔断10秒,时间过了之后,会有一个请求可以通过,如果这个请求的时间小于2000毫秒,则结束熔断,如果大于,则再次熔断
1.8的sentinel控制台的慢调用比例的前端页面有问题,比例阈值传递只能选1
-
异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
6个请求内如果超过了百分50的请求出现异常,则开始熔断10秒,接下来也是一个请求如果不会异常就不熔断 -
异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
6个请求里面如果5个异常,就熔断10秒
热点规则
@SentinelResource
sentinel 默认返回的降级都是 Blocked by sentinel . 如果想要使用自定义的返回则想要用 @SentinelResource
注解
资源名就是 @SentinelResource
里面的value,参数索引从0开始.该热点限流意思是请求包含p1的请求QPS 超过了5,则降级.降级持续10秒
例外项
普通情况下p1 的请求的QPS只能是5,但是假设p1的里面的值是g的时候,QPS可以达到2000
注意, @SentinelResource 只能处理控制台的限流情况,如果方法内出现了异常,并不能捕获到.
系统规则
整个系统的控制.
@SentinelResource 配置
原始的自定义降级方法需要自己写callback,每个方法都需要写一个对应的降级方法,冗余太多了.
自定义限流处理逻辑
- 创建全局异常处理类. 必须使用static方法,入参必须要有BlockException e
public class CustomerHandler {
public static String handler01(BlockException e){
return "全局异常处理01";
}
public static String handler02(BlockException e){
return "全局异常处理02";
}
}
- @SentinelResource 里面写上处理类和方法
@GetMapping("/test05")
@SentinelResource(value = "test05"
,blockHandlerClass = CustomerHandler.class
,blockHandler = "handler01")
public String test05(@RequestParam(value = "p1",required = false) String p1,
@RequestParam(value = "p2",required = false) String p2){
return "ok";
}
sentinel 整合 openfeign
@SentinelResource 中fallback管运行时异常
blockHandler 管配置违规
- 引入 feign 和 sentinel 的 pom
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 配置文件里面开启 feign 对sentinel 的支持
feign:
sentinel:
enabled: true
- 主启动类上添加 @EnableFeignClients
- feign 上添加 @FeignClient(value = “provider-01”,fallback = ProviderClientImpl.class) fallback 属性,创建 impl 实现方法
记得@component
坑
Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata
原因是我 父工程依赖的环境是
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring-cloud-alibaba-dependencies 2.2.0 依赖的 feign 核心方法写错
了.
解决方法
把 spring-cloud-alibaba-dependencies 2.2.0 提升到 2.2.1
规则持久化
将配置信息存储到 nacos 或者 zookeeper 中. 由于项目不一定使用了nacos,所以这次使用通用的zookeeper 来作为配置中心
- 引入pom文件
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
</dependency>
- github上下载sentinel源码,修改dashboard工程中 pom文件依赖,注释掉test作用域
- 将 test下的类拷贝到src下
- 将图中的注入改成刚导入的类
- 修改html
- 在工程中读取流控规则从zookeeper中读取
@Configuration
public class ZookeeperSentinelConfig {
@Value("${spring.application.name}")
private String appName;
@PostConstruct
public void loadRules() {
final String remoteAddress = "127.0.0.1:2181";
final String path = "/sentinel_rule_config/" + appName;
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}