Sentinel 是阿里巴巴开源的分布式系统的流量防卫组件,Sentinel 把流量作为切入点,从流量控制,熔断降级,系统负载保护等多个维度保护服务的稳定性。
本示例演示如何使用 Sentinel starter 完成 Spring Cloud 应用的限流管理。
Sentinel 提供了两种配置限流规则的方式:代码配置 和 控制台配置。本示例使用的方式为通过控制台配置。代码配置可参考Sentinel 官方文档
控制台
1. 下载控制台
2. 启动控制台
控制台为springboot应用,直接使用命令java -jar java -jar sentinel-dashboard.jar
,默认的端口为8080
快速开始
1. 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. 限流埋点
-
HTTP埋点
Sentinel starter 默认为所有的 HTTP 服务提供了限流埋点,如果只想对 HTTP 服务进行限流,那么只需要引入依赖,无需修改代码。
-
自定义埋点
如果需要对某个特定的方法进行限流或降级,可以通过 @SentinelResource 注解来完成限流的埋点
@SentinelResource("test") @GetMapping("test") public String test(){ return "test"; }
也可以通过原始的
SphU.entry(xxx)
方法进行埋点。Sentinel 官方文档
3. application.yml
server:
port: 8040
spring:
application:
name: sentinel-example
cloud:
sentinel:
transport:
# 控制台地址
dashboard: localhost:8080
限流规则
1. 访问控制台
访问http://localhost:8080页面,左侧就会出现注册的应用,点击流控规则
即可看到当前的限流。如果控制台中没有应用,则需要访问一下接口,因为 Sentinel 使用了lazyload策略。
2. 配置http url限流
url为绝对路径,为方便测试阈值设置为1
访问http://localhost:8040/hello,当QPS大于1时,返回默认的错误信息
Blocked by Sentinel (flow limiting)
3. 配置自定义限流
点击新增流控规则,资源名填写 @SentinelResource 注解 value 字段的值
访问http://localhost:8040/test,当QPS大于1时,返回spring默认的500错误页面
限流处理
1. 默认的限流异常处理
默认的限流异常处理返回Blocked by Sentinel (flow limiting)
,如需自定义返回信息,需要实现BlockExceptionHandler
接口
@Component
public class CustomBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
PrintWriter writer = response.getWriter();
writer.write("current limiting");
writer.flush();
writer.close();
}
}
2. @SentinelResource注解的限流异常处理
如果需要自定义处理逻辑,填写 @SentinelResource 注解的 blockHandler 属性(针对所有类型的 BlockException,需自行判断)或 fallback 属性(针对熔断降级异常),注意对应方法的签名和位置有限制,详情见 Sentinel 注解支持文档
@RestController
public class TestController {
/*
blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,
参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。
blockHandler 函数默认需要和原方法在同一个类中。
若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,
注意对应的函数必需为 static 函数,否则无法解析。
fallback函数针对熔断降级异常
*/
@SentinelResource(value = "test", blockHandler = "testHandler", fallback = "testFallback")
@GetMapping("test")
public String test(){
// 模拟异常,进入fallback
// throw new RuntimeException();
return "test";
}
@GetMapping("hello")
public String hello(){
return "hello";
}
public String testHandler(BlockException e){
return "test limiting";
}
public String testFallback() {
return "test error";
}
}
Datasource
由于控制台配置为内存型,应用重启后限流就会重置。所以选择使用动态规则配置,即使应用重启限流依然存在。
1. application.yml
spring:
application:
name: sentinel-example
cloud:
sentinel:
transport:
# 控制台地址
dashboard: localhost:8080
datasource:
# ds1为datasource的名称,file为datasource的类型
ds1.file:
# 文件地址
file: classpath:flowrule.json
# 规则类型,flow为限流
rule-type: flow
# 规则数据的类型,默认为json
data-type: json
# 除file类型都需要引入对应的依赖
ds2.nacos:
server-addr: localhost:8848
data-id: flowrule.json
rule-type: flow
2. 规则数据
[
{
"resource": "/hello",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
},
{
"resource": "/test",
"controlBehavior": 0,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0
}
]
常量参考RuleConstant
类
resource:资源名称
controlBehavior:流量控制,0为直接拒绝
count:限流阈值
grade:限流阈值类型,1为QPS
limitApp:根据调用方限流,default为不区分调用者
strategy:根据调用关系选择策略,0为直连