这一篇我们主要介绍下Sentinel控制的使用(主要是结合SpringBoot),主要介绍其的一些配置作用,以及分析下其对web请求endpoint的处理
一、控制台安装
这个我们去官网下载sentinel-dashboard,然后本地编译:
编译后其就会有一个有一个jar,我们直接运行就可以了:例如java -Dserver.port=9000 -jar sentinel-dashboard-1.8.3.jar
之后我们就能访问了:http://localhost:9000
:
输入默认账号密码:sentinel/sentinel
:
二、spring-boot项目使用
然后就是spring-boot
那边的处理了,由于当前控制台的版本是1.8.3
,所以spring-cloud-starter-alibaba-sentinel
需要使用2021.0.1.0
,其引用的包就会是1.8.3
,同时配套的spring-boot-starter-parent
也要到2.6.x
及以上。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.0.1.0</version>
</dependency>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
spring.application.name=Sentinel-Boot-Project
spring.cloud.sentinel.transport.dashboard=localhost:9000
这个就是配置文件的简单配置,也就是配置控制台的访问地址。
@RestController
@RequestMapping("sentinel")
public class SentinelController {
@GetMapping("simpleTest")
public String simpleTest(){
return "--------simpleTest";
}
@GetMapping("paramTest")
public String paramTest(@RequestParam("param1") String param1){
return "--------paramTest";
}
@SentinelResource(value = "simpleAnnotation")
@GetMapping("simpleAnnotation")
public String simpleAnnotation(){
return "--------simpleAnnotation";
}
}
然后我们就准备这个Controller
启动spring-boot
项目,注意我们启动后,在控制台界面仍然是看不到内容的,我们需要访问一个连接后才能看到,例如我们访问http://localhost:8080/sentinel/simpleTest
等这些请求
这里我们就能看到我们请求监控了。
同时簇点链路能看到我们在controller定义的请求,但我们注意这个树状关系。
这里的关系最前面一层是sentinel_spring_web_context
,这个表示其下面是当前应用的所有api,也就是endpoint
。然后下面再有以及simpleAnnotation
,这里也就有3个endpoint
资源。然后通过controller
我们知道
这两个是sentinel
本身记录的,我们并没有加@SentinelResource
表面这个是sentinel
的资源,但我们可以看到其默认的资源key
是api
的请求地址。而我们加了@SentinelResource
的,可以看到其的资源key
是我们指定的simpleAnnotation
,而不是请求的地址。
@SentinelResource(value = "simpleAnnotation")
@GetMapping("simpleAnnotation")
public String simpleAnnotation(){
return "--------simpleAnnotation";
}
然后我们可以看到后面的流控
、熔断
这些就可以通过dashboard
来配置其的规则了。
三、规则配置
1、流量控制
我们来试下sentinel
自己自动获取到的endpoint
。
我们可以看到这里设置的属性,就是我们前面文章通过自己设置规则的那些参数,看了前面那几篇文章应该对这些配置的内容并不陌生了,目前这种我们设置阈值
为2,来看下效果:
我们新增后就可以在流控规则
看到我们配置的信息。我们请求几次,就可以看到返回的默认流控信息。
然后在事实监控
就可以看到流控设计通过、阻塞的信息。
2、熔断降级
然后这是熔断降级的信息配置,同时根据熔断策略的不同,我们配置的信息也是不同的,目前是慢比例,然后异常比例、异常树,其的提示是不同的,不过通过前面篇我们可以知道,这两个都是设置的count
的值。
Sentinel 提供以下几种熔断策略:
- 慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
- 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
- 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
Field | 说明 | 默认值 |
resource | 资源名,即规则的作用对象 | |
grade | 熔断策略,支持慢调用比例/异常比例/异常数策略 | 慢调用比例 |
count | 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值 | |
timeWindow | 熔断时长,单位为 s | |
minRequestAmount | 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) | 5 |
statIntervalMs | 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) | 1000 ms |
slowRatioThreshold | 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入) |
然后要参数这个熔断的话,我们在controller
中再添加一个GetMapping
。
@SentinelResource(value = "exceptionAnnotation",blockHandler = "blockHandler")
@GetMapping("exceptionAnnotation")
public String exceptionAnnotation(){
if (index++%2 == 0){
throw new NullPointerException();
}
return "--------simpleAnnotation";
}
public String blockHandler(BlockException blockException){
return "exceptionAnnotation Block Exception";
}
同时这里我们自己添加了一个异常处理器blockHandler(BlockException blockException)
然后我们看下效果:
通过这个数据我们可以看看到,在中间的3秒内,其都有柱塞。
3、热点参数
这些参数也与我们自动设置的是差不多的。
但这里我试了,按目前这种方法,也就是我们不写@SentinelResource
内容,加了热点规则,也任然是控制不了的:
@GetMapping("paramTest")
public String paramTest(@RequestParam("param1") String param1){
return "--------paramTest";
}
所以我们要将@SentinelResource
,加上,建议不管是使用流量控制、熔断这些,如果要使用sentinel
控制,都加上@SentinelResource
@GetMapping("paramTest")
@SentinelResource(value = "paramTest",blockHandler = "paramTestHandler")
public String paramTest(@RequestParam("param1") String param1){
return "--------paramTest";
}
public String paramTestHandler(String param1,BlockException blockException){
return "paramTestHandler Block Exception";
}
我们这样写之后,就能控制了:
4、系统控制
对于系统控制,其的使用,要在使用@SentinelResource
的时候,标注其为入口流量,默认是出口,例如:
public @interface SentinelResource {
/**
* @return name of the Sentinel resource
*/
String value() default "";
EntryType entryType() default EntryType.OUT;
@SentinelResource(value = "simpleAnnotation",entryType = EntryType.IN)
@GetMapping("simpleAnnotation")
public String simpleAnnotation(){
return "--------simpleAnnotation";
}
然后其的配置,你可以配置系统 load
、线程数
、QPS
等,这些概率以及这几个设置的控制顺序我们前面文章有梳理。
例如这里你可以从各个方面进行设置: