sentinel是alibaba提供的应用于分布式框架中的流控限流检测组件,功能十分的强大,比hystrix功能还要强大。并且sentinel主要通过dashboard来完成微服务的配置。减少了代码量,减少了耦合程度
一. sentinel的安装启动
sentinel的官网链接:https://github.com/alibaba/Sentinel,可以查看官网文档说明
可以通过https://github.com/alibaba/Sentinel,选择版本,直接下载jar包,但是github的速度,你懂得。此时可以去网上找一些国内的云平台下载sentinel
下载好jar包后,直接通过Java -jar 启动jar包即可,可运行在win、Linux,sentinel账号名密码登录即可,默认端口8080
sentinel是启动的懒加载模式,所以,所有注册到sentinel上的微服务需要第一次访问才可以在sentinel监控到
二. sentinel的流控
sentinel可以通过控制添加流控的方式,对访问某个URL的访问QPS以及线程数进行控制。
可以设置阈值类型、流控模式、流控效果,接下来将逐个讲解含义
2.1 阈值类型
- QPS:
简言之,就是设定了该资源访问时,一秒钟内的访问次数,如果超过该阈值,就会停止访问,返回错误响应
- 线程
类型为线程时,指定了该资源访问时,同时并发线程数不能超过该值。
2.2 流控效果
- 快速失败:
当超过阈值时,立马失败,返回错误页面
- warm up(预热):
,该模式需要设置预热时长,加入设置预热时长为10秒,QPS为8,当流量进行访问时,会在10秒的预热期内将QPS上升至8。10秒以内的QPS都是<8的。
- 排队等待:
该模式有点绕,难理解。简言之: QPS为5,超时时间为500MS,则表示,一秒钟处理5个请求,如果发起的请求超时时间超过500ms,则返回错误信息
如图,当这样设置时,意思是QPS为1,就是一秒钟处理一个请求。如果有10个请求同时进来,第一个请求成功,第二个请求如果等待时间超过超时时间1,则返回错误信息。此时剩余9个请求均失败
如图,意思是QPS为1,则一秒钟处理一个请求(如果QPS为10,则表示100ms处理一个请求),超时时间为100秒,如果此时有10个请求同时进来,第一个要处理1秒返回,第二个要等待1秒等第一个结束后在处理,此时只要等待时间不超过100秒,则所有的请求都会排队进行处理,如果等待时间超过了100秒,则返回错误信息。
2.3 流控模式
流控模式是指流控以什么模式进行
- 直接模式
该模式就是针对配置的资源本身进行流控
- 关联模式
该模式表示,当test2的请求达到阈值时,test1这个资源会控制访问,返回错误信息
该模式在被高流量冲击时,旨在保护test2。例如,秒杀系统中,test1是下单接口,test2是支付接口,当支付接口超过5QPS时,就不允许再继续下单了,斗则支付接口可能处理不过来。导致异常。
- 链路模式
目前还没有搞懂链路模式的含义,但感觉实用性不是很强。
三. sentinel的降级熔断
sentinel的降级熔断机制类似于hystrix的熔断机制。可以再sentinel的web页面进行配置完成降级熔断策略
主要有以上三种降级策略,下面分别讲解这三种策略的使用含义
3.1 RT
RT的意思是指,1秒内的请求数如果超过5个,&&并且每个请求的平均响应时间超过了RT设置的500毫秒,则在下一个1秒(窗口期)内,该服务会被降级,会返回错误页面。
3.2 异常比例
顾名思义,就是单位时间内(默认:一秒内5次请求的比例),请求出现的异常达到一定比例,则在指定的时间窗口期内(如上图,就是在10秒内都不可访问),该URL会被降级,返回错误信息。窗口期结束后,恢复正常
官网解释:
- 异常比例 (
ERROR_RATIO
):当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0]
,代表 0% - 100%。
3.3 异常数
顾名思义,就是微服务在单位时间内,出现的异常数超过阈值,就会被降级。并能存在半开状态,官网解释如下:
当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
超过阈值熔断后,将会抛出BlockException,并且执行@SentinelResource中指定的blockHandler方法进行响应
如果时间窗口期结束后,再次请求还是异常,则会再次被熔断
四. 热点规则
热点规则可以用来对参数进行限流。目前支持:
- 对指定URL的指定参数进行限流
- 对指定参数的指定值进行额外限流
注意事项(防采坑)
@RequestMapping(value = "/sentinel/test3", method = RequestMethod.GET)
@SentinelResource(value = "test3", blockHandler = "test2Handler", fallback = "test2Fallback")
public String test3(String a, String b) {
System.out.println(System.currentTimeMillis() + "这是第test3");
return "this is test3";
}
public String test2Handler(String a, String b, BlockException e) {
System.out.println("走了");
return "这是限流异常";
}
public String test2Fallback() {
return "这是降级异常";
}
- 针对如上URL配置热点规则时,需要对SentinelResource中配置的test3进行配置,对URL地址配置无效
- 如果达到了阈值,sentinel就会抛出 'BlockException' 则会执行SentinelResource中的blockHandler指定的方法。
配置规则:
*** 如上配置,则表示参数下标为0时,一秒内访问的阈值是1次,超过后会被熔断,时间窗口期为10秒,即10秒内用户访问均是被熔断状态。
*** 此时配置,表示针对下标为0的参数,配置了例外项,如果该参数的值为qq的话,则配置阈值为200。也就是当第0个参数值为qq时,阈值就不是1了,而是200,作为额外项。
五. @SentinelResource
各个参数说明:
- value
指定资源名,可在sentinel控制台针对该资源民配置策略
- blockHandler(违背sentinel控制台规则的兜底方法,不只是限流规则)
当被限流后,指定的兜底方法。包括流控规则、热点规则、降级配置等sentinel控制的规则不符合后,的访问指定方法,值为方法名,注意方法需要与URL方法参数一致,并且添加参数BlockException
public String test2Handler(@RequestParam(value = "a", required = false) String a,
@RequestParam(value = "b", required = false) String b,
BlockException e) {
System.out.println("走了");
return "这是限流异常";
}
- blockHandlerClass
如果不希望限流兜底方法与业务逻辑耦合,则可以将handle方法提取出来成为一个类,用blockHandlerClass指定class类型,然后再指定handle方法(此时主要方法需要设定为static)
- fallback(与sentinel配置无关,仅仅对URL异常生效)
当访问的方法出现运行时异常时,sentinel不配置任何降级规则,方法也会执行fallback指定的兜底方法,相当于hystrix的服务降级。方法参数要与URL参数一致
public String test2Fallback(@RequestParam(value = "a", required = false) String a,
@RequestParam(value = "b", required = false) String b,Throwable e) {
return "这是降级异常";
}
- exceptionsToIgnore
指定忽略的异常
@SentinelResource(value = "test3", blockHandler = "test2Handler", fallback = "test2Fallback",
exceptionsToIgnore = {NullPointerException.class})
六. sentinel的持久化配置
sentinel的持久化,需要配合nacos,将sentinel配置规则持久化到nacos中。
①需要持久化的微服务首先导入依赖:
<!--sentinel持久化到nacos--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
②编写微服务的yml文件:
在nacos中编写配置文件:sentinel-test
在sentinel中指定DataSource为nacos,并指明nacos的配置文件服务地址,namespace,group、dataId、配置文件类型为json
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: 124.71.112.168:8089
dataId: sentinel-test
groupId: dev
namespace: 108d4e5c-f757-43ab-af83-67e352a5b625
data-type: json
rule-type: flow
③在nacos中编写配置文件sentinel-test
[
{
"resource":"/sentinel/test1",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]
解释如下:
resource: 资源名称
limitApp: 来源应用
grade: 阈值类型,0 表示线程数,1 表示 QPS
count:单机阈值
strategy:流控模式,0 表示直接,1表示关联,2表示链路
controlBehavior: 流控效果,0 表示快速失败 ,1 表示 Warm Up ,2 表示排队等待
clusterMode: 是否集群
④启动微服务,访问sentinel,此时该服务的sentinel限流规则已经持久化到sentinel中了。