Sentinel之限流、降级、系统保护、热点、授权规则
简介Sentinel是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。本文主要讲限流、熔断降级、热点、系统保护、授权等方面,并持久化到Nacos中。安装sentinel控制台官方下载地址:https://github.com/alibaba/Sentinel/releases提供1.7的
简介
Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。
本文主要讲限流、熔断降级、热点、系统保护、授权等方面,并持久化到Nacos中。
安装sentinel控制台
官方下载地址:https://github.com/alibaba/Sentinel/releases
提供1.7的版本:https://pan.baidu.com/s/1JS2tP_7T0Coh4lE5tEOX5Q 提取码:tffz
启动命令:
nohup java -server -Xms256m -Xmx256m -jar -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=sentinel -Dserver.port=9090 -Dserver.servlet.session.timeout=7200 sentinel-dashboard-1.7.0.jar > sentinel.log 2>&1 &
访问: http://localhost:9090/#/dashboard/home 账号密码都是: sentinel
默认用户名和密码都是 sentinel。也可指定用户名密码:
- Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel;
- Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456;
- Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间,如 7200 表示 7200 秒;60m 表示 60 分钟,默认为 30 分钟;

增加相应依赖
除了sentinel依赖,还需要增加持久化依赖。如果不持久化,服务每次重启后,规则策略都需要重新配置。
sentinel提供的持久化配置中心有redis、nacos、zk、file等,我选用的是Nacos,前文也介绍了Nacos作为配置中心的搭建过程。
-
<!--sentinel--> -
<dependency> -
<groupId>com.alibaba.cloud</groupId> -
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> -
</dependency> -
<!--sentinel持久化到nacos--> -
<dependency> -
<groupId>com.alibaba.csp</groupId> -
<artifactId>sentinel-datasource-nacos</artifactId> -
</dependency>
增加项目配置项
-
spring: -
application: -
name: gourdhu-service -
cloud: -
# nacos-配置 -
nacos: -
# 配置中心 -
config: -
server-addr: 47.103.5.190:8848 -
file-extension: yaml -
encode: UTF-8 -
group: GOURD -
namespace: 0d1fc564-ffec-4670-a634-77b4c607d80f -
# sentinel 流控 -
sentinel: -
# 取消Sentinel控制台懒加载 -
eager: true -
# 控制台地址 -
transport: -
port: 8719 -
dashboard: 10.10.10.100:9090 -
# 持久化数据库-nacos -
datasource: -
# 限流 -
flow: -
nacos: -
dataId: ${spring.application.name}-sentinel-flow.json -
groupId: GOURD -
# 规则 -
ruleType: flow -
server-addr: ${spring.cloud.nacos.config.server-addr} -
# 熔断降级 -
degrade: -
nacos: -
dataId: ${spring.application.name}-sentinel-degrade.json -
groupId: GOURD -
# 规则 -
ruleType: degrade -
server-addr: ${spring.cloud.nacos.config.server-addr} -
# 系统保护 -
system: -
nacos: -
dataId: ${spring.application.name}-sentinel-system.json -
groupId: GOURD -
# 规则 -
ruleType: system -
server-addr: ${spring.cloud.nacos.config.server-addr} -
# 授权 -
authority: -
nacos: -
dataId: ${spring.application.name}-sentinel-authority.json -
groupId: GOURD -
# 规则 -
ruleType: authority -
server-addr: ${spring.cloud.nacos.config.server-addr} -
# 热点 -
hot: -
nacos: -
dataId: ${spring.application.name}-sentinel-hot.json -
groupId: GOURD -
# 规则 -
ruleType: param_flow -
server-addr: ${spring.cloud.nacos.config.server-addr}
Nacos配置文件内容
限流规则配置:
-
[{ -
"resource": "resource", -
"limitApp": "default", -
"grade": 1, -
"count": 2, -
"strategy": 0, -
"controlBehavior": 0, -
"clusterMode": false -
}] -
# resource: 资源名 -
# limitApp-流控应用: default(所有) -
# grade-阈值类型: qps(1),线程数(0) -
# count-单机阈值: 每秒2次 -
# strategy-流控模式: 直接(0),关联(1),链路(2) -
# controlBehavior-流控方式: 快速失败(0),Warm Up(1),排队等待(2)
Nacos中配置:

Sentinel控制台显示:

熔断降级规则配置:
-
[{ -
"resource": "resource", -
"limitApp": "default", -
"count": 60000, -
"grade": 0, -
"timeWindow": 20 -
}] -
# grade-阈值类型: 异常比例(1),RT(0) -
# timeWindow-时间窗口:降级时间间隔, 单位秒
热点规则配置:
-
[{ -
"resource": "hot-resource", -
"limitApp": "default", -
"grade": 1, -
"paramIdx": 0, -
"count": 1, -
"controlBehavior": 0, -
"maxQueueingTimeMs": 0, -
"burstCount": 0, -
"durationInSec": 1, -
"paramFlowItemList": [], -
"clusterMode": false -
}] -
# paramIdx: 参数索引,从0开始 -
# durationInSec:统计窗口时长,默认1s -
# paramFlowItemList:参数例外项
系统保护规则配置:
-
[{ -
"highestSystemLoad": -1, -
"qps": 200, -
"avgRt": -1, -
"maxThread": -1, -
"highestCpuUsage": -1 -
}] -
# -1表示失效
授权规则配置:
-
[{ -
"resource": "auth-resource", -
"limitApp": "default", -
"strategy": 0 -
}] -
# strategy: 授权规则,0-白名单(默认),1-黑名单
授权规则限制可以用一句话就说明:如果配置的策略是黑名单且requester在配置在limitApp中,则请求拦截;如果配置的策略是白名单且requester在配置不在limitApp中,则请求拦截;否则请求不拦截。
至此,sentinel 的整合就好了,下面启动项目,开始测试
启动项目测试
启动成功后,在控制台看到以下输出,说明配置成功

或者直接去sentinel控制台查看流控、降级、系统规则中是否存在记录:

Jmeter测试
增加限流接口,并埋点@SentinelResource:
-
@GetMapping("/sentinel") -
@SentinelResource(value="resource") -
@ApiOperation(value = "测试sentinel限流") -
public BaseResponse sentinelTest() { -
return BaseResponse.ok("success!"); -
} -
@GetMapping("/sentinel-hot") -
@SentinelResource(value="hot-resource") -
@ApiOperation(value = "测试sentinel热点") -
public BaseResponse sentinelHot(String hotkey) { -
return BaseResponse.ok("success! hotkey: "+hotkey); -
}
增加异常处理器:
-
/** -
* 异常处理器 -
* @author gourd -
*/ -
@RestControllerAdvice -
@Slf4j -
public class GlobalExceptionHandler { -
/** -
* 处理Sentinel异常 -
* @param e -
* @return -
*/ -
@ExceptionHandler(value = UndeclaredThrowableException.class) -
public BaseResponse badRequestException(UndeclaredThrowableException e) { -
Throwable undeclaredThrowable = e.getUndeclaredThrowable(); -
// 打印堆栈信息 -
log.error("异常信息:",undeclaredThrowable); -
if(undeclaredThrowable instanceof FlowException){ -
return BaseResponse.failure("限流啦!"); -
}else if(undeclaredThrowable instanceof DegradeException){ -
return BaseResponse.failure("熔断降级啦!"); -
}else if(undeclaredThrowable instanceof ParamFlowException){ -
return BaseResponse.failure("热点限流啦!"); -
}else if(undeclaredThrowable instanceof AuthorityException){ -
return BaseResponse.failure(HttpStatus.UNAUTHORIZED.value(),"授权限制了!"); -
} -
return BaseResponse.failure("未知异常!"); -
} -
}
测试限流:
我配置的策略类型是QPS。
我们配置的单机QPS是2,也就是说resource资源一秒内只会处理2个请求,其他请求会快速失败返回。Jmeter并发数为3,循环1次。

测试熔断降级:
为了方便测试,我们把熔断超时时间改为1s,并把限流qps改大为50,并在接口中设置线程睡眠 1.1s,模拟超时。Jmeter并发数为1,循环10次。
我配置的策略类型是RT。
平均响应时间 (DEGRADE_GRADE_RT):当资源的平均响应时间超过阈值(DegradeRule 中的 count,以 ms 为单位)之后,资源进入准降级状态。接下来如果持续进入 5 个请求,它们的 RT 都持续超过这个阈值,那么在接下的时间窗口(DegradeRule 中的 timeWindow,以 s 为单位)之内,对这个方法的调用都会自动地返回(抛出 DegradeException)。

测试热点数据限流:
设置限流阙值为1,统计窗口时间为1s,参数索引为0,即以接口第一个参数为热点,一个热点参数一秒内只接受一个请求。
Jmeter增加两个http请求,传不同的参数,并发数为3。

测试系统保护:
我配置的策略类型是QPS,为了方便测试,设置QPS值为5,Jmeter并发数为10,循环1次。

更多推荐


所有评论(0)