蒲公英追逐旳不只是天空,还有一份自由。
核心组件Sentinel
Sentinel简介
随着微服务的流行,服务和服务之间的稳定性变得越来越重要;Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel特性
(1)丰富的应用场景:承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀,可以实时熔断下游不可用应用; (2)完备的实时监控:同时提供实时的监控功能。可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况; (3)广泛的开源生态:提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合; (4)完善的 SPI 扩展点:提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。
Sentinel安装
执行命令启动Sentinel控制台
默认端口8080,登录账号密码均为sentinel
java -jar sentinel-dashboard-1.8.5.jar --server.port=8080
Sentinel应用
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
bootstrap.yml
server:
port: 9401
spring:
application:
name: btks-authorization
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #Nacos地址
config:
server-addr: 127.0.0.1:8848 #Nacos地址
file-extension: yaml #这里我们获取的yaml格式的配置
sentinel:
transport:
dashboard: localhost:8080
流控规则
@SentinelResource(value = "/oauth/token",blockHandler = "handleException")
我们可以根据@SentinelResource注解中定义的value(资源名称|路径)来进行限流操作,但是需要指定限流处理逻辑。Sentinel采用的懒加载规则,需要我们先访问下接口,Sentinel控制台中才会有对应服务信息,我们先访问下该接口:http://localhost:9101/authorization/oauth/token。
1、设置阈值类型QPS单机阈值(单机阈值必须大于等于0)0,再次访问http://localhost:9101/authorization/oauth/token时, Blocked by Sentinel (flow limiting) 直接被流量限制访问。
自定义处理逻辑
@Configuration
public class CustomBlockHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException blockException) throws IOException {
httpServletResponse.setStatus(HttpStatus.OK.value());
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json;charset=utf-8");
httpServletResponse.setHeader("Content-Type","application/json;charset=utf-8");
if (blockException instanceof FlowException) {
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"接口限流啦!",blockException));
} else if (blockException instanceof DegradeException) {
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"服务降级啦!",blockException));
} else if (blockException instanceof ParamFlowException) {
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"热点参数限流啦!",blockException));
} else if (blockException instanceof SystemBlockException) {
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"系统规则(负载/...不满足要求)!",blockException));
} else if (blockException instanceof AuthorityException) {
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"授权规则不通过!",blockException));
}else{
new ObjectMapper().writeValue(httpServletResponse.getWriter(),BtJsonResult.build(BtJsonResult.SUCCESS,"未知异常!",blockException));
}
}
}
blockHandlerClass
@SentinelResource(value = "/oauth/token",blockHandler = "handleException",blockHandlerClass = CustomBlockHandler.class)
1、设置阈值类型QPS单机阈值(单机阈值必须大于等于0)0,再次访问http://localhost:9101/authorization/oauth/token时,
{
"status": "200",
"msg": "接口限流啦!",
"data": {
"cause": null,
"stackTrace": [],
"rule": {
"resource": "/oauth/token",
"limitApp": "default",
"grade": 1,
"count": 0,
"strategy": 0,
"refResource": null,
"controlBehavior": 0,
"warmUpPeriodSec": 10,
"maxQueueingTimeMs": 500,
"clusterMode": false,
"clusterConfig": {
"flowId": null,
"thresholdType": 0,
"fallbackToLocalWhenFail": true,
"strategy": 0,
"sampleCount": 10,
"windowIntervalMs": 1000
}
},
"ruleLimitApp": "default",
"localizedMessage": null,
"message": null,
"suppressed": []
}
}
Sentinel熔断降级与Feign整合
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在application.yml中打开Sentinel对Feign的支持:
feign:
sentinel:
enabled: true #打开sentinel对feign的支持
声明降级逻辑:
@Component
public class BtAccountApFallbackService implements BtAccountApiService {
......
}
指定降级逻辑:
@FeignClient(name = AccountConstant.SERVICE_NAME,url = "${FeignClient.btks-account}",fallback = BtAccountApFallbackService.class)
测试发现Sentinel熔断降级生效。
Sentinel 限流规则持久化
pom.xml 添加相关依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
Nacos 配置限流规则
application.yml 数据源配置
重启应用,测试发现流控规则中已经有该配置了,并且修改Nocos中的配置发布,实时同步。