一、下载与安装
演示版本1.8.0
1.1 下载地址
1.2 安装
sentinel本身是jar包的web服务,所以直接用java命令启动即可
java -jar sentinel-dashboard-1.8.0.jar
启动成功
根据启动页面,可以推测出sentinel是基于springboot开发的。
二、springboot集成sentinel
2.1 引入maven依赖
<!-- sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
2.2 添加配置文件
sentinel:
transport:
dashboard: 127.0.0.1:8080 #sentinel的默认启动端口
2.3 在controller接口添加注解
@SentinelResource(value = "", blockHandler = "", fallback = "")
- value: sentinel对应的资源名,默认是接口名称
- fallback: 异常处理方法名称
- blockHandler: 限流/降级对应的方法名称
注:fallback和blockHandler的方法参数必须要与controller的方法参数相同
(1) fallback在最后一个参数后加上Throwable类型的入参,可以捕获到controller的方法发生的异常。 (2) blockHandler在最后一个参数后加上BlockException类型的入参,可以捕获到是触发了限流规则还是降级规则
@GetMapping("method")
@SentinelResource(value = "method", fallback = "fallback", blockHandler = "blockHandler")
public void method(Object param) {
// 方法体
}
public void fallback(Object param, Throwable e) {
System.out.println(e);
}
public void blockHandler(Object param, BlockException e) {
if (e instanceof DegradeException) {
throw new RuntimeException("服务降级,请稍后再试");
}
if (e instanceof FlowException) {
throw new RuntimeException("服务流控,请稍后再试");
}
}
2.4 测试sentinel
2.4.1 测试sentinel的熔断机制
@GetMapping("method")
@SentinelResource(value = "method", fallback = "fallback")
public void method(Object param) {
// 方法体
throw new RuntimeException("测试熔断");
}
public void fallback(Object param, Throwable e) {
if (e instanceof Exception) {
System.out.println("测试熔断成功");
}
}
请求127.0.0.1:服务端口/method, 可以看到控制台打印测试熔断成功
2.4.1 测试sentinel的限流机制
@GetMapping("method")
@SentinelResource(value = "method", blockHandler = "blockHandler")
public SimpleMessage method(Object param) {
// 方法体
return new SimpleMessage(200, "访问成功");
}
public SimpleMessage blockHandler(Object param, BlockException e) {
if (e instanceof DegradeException) {
return new SimpleMessage(201, "服务降级,请稍后再试");
}
if (e instanceof FlowException) {
return new SimpleMessage(201, "服务流控,请稍后再试");
}
return new SimpleMessage(ErrorCodeEnum.NO);
}
浏览器访问127.0.0.1:8080,看到没有任何配置信息。因为sentinel是懒加载,所以访问接口才会有资源信息。
访问127.0.0.1:服务端口/method后,再打开sentinel
可以看到访问链路,在链路的设置流控/降级规则,设置规则的资源名要和@SentinelResource配置的value相同
设置每秒QPS不能超过5个。
多线程请求
public static void main(String[] args) {
// 1.1发送10个请求触发限流
for (int i = 0; i < 10; i++) {
new Thread(() -> {
String resp = HttpClient.get("http://127.0.0.1:10004/method", 3000, 3000);
System.out.println(resp);
}).start();
}
// 预期结果,5个被拦截,5个通过
}
结果
2.4.2 测试sentinel的降级机制
10个请求内如果请求超过10 * 0.5个响应时间超过1000ms, 则触发5秒钟的降级机制
@GetMapping("method")
@SentinelResource(value = "method", blockHandler = "blockHandler")
public SimpleMessage method(Object param) throws InterruptedException {
TimeUnit.SECONDS.sleep(1000);
// 方法体
return new SimpleMessage(200, "访问成功");
}
public SimpleMessage blockHandler(Object param, BlockException e) {
if (e instanceof DegradeException) {
return new SimpleMessage(201, "服务降级,请稍后再试");
}
if (e instanceof FlowException) {
return new SimpleMessage(201, "服务流控,请稍后再试");
}
return new SimpleMessage(ErrorCodeEnum.NO);
}
测试请求
public static void main(String[] args) throws InterruptedException {
// 发送10个慢请求触发降级
for (int i = 0; i < 10; i++) {
new Thread(() -> {
String resp = HttpClient.get("http://127.0.0.1:10004/method", 3000, 3000);
}).start();
}
/*
* 再每隔一秒发送1个请求,因为降级持续时间是5秒,所以第六个请求开始接口就会恢复正常
*/
for (int i = 0; i < 10; i++) {
String resp = HttpClient.get("http://127.0.0.1:10004/method", 3000, 3000);
System.out.println(resp);
TimeUnit.SECONDS.sleep(1);
}
// 预期结果,5个被拦截,5个通过
}