Java:(一)Sentinel初探-接口限流
前言
最近在做一个小项目,对限流有些要求,遂想到引入Sentinel来实现
下面记录一下大致步骤:
Sentinel Dashboard
先按照官方文档的要求,将Dashboard下载跑起来,可以下载jar包直接跑,或者把项目clone下来,直接跑Dashboard这个子项目

jar包(项目)跑起来后默认端口是8080,也可以可使用 -Dserver.port=新端口 进行设置
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
项目中引入
我是SpringBoot单体项目,先引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.1</version>
</dependency>
然后在项目yml文件中引入sentinel的配置
spring:
application:
name: screen
cloud:
sentinel:
transport:
port: 996 # 本机提供给dashboard控制台调用的端口
dashboard: localhost:8080 # dashboard控制台的地址
创建一个测试接口
@RestController
@RequestMapping("idx")
public class IdxController {
@GetMapping("test")
public RestResult<String> test() {
return RestResult.ok("调用成功");
}
}
正常调用的话返回了成功
{"code":0,"msg":"调用成功","data":null}
然后登录sentinel控制台:localhost:8080,默认账号密码为sentinel(线上建议改掉)

我们访问接口后,控制台实时监控区域就可以看到刚刚的访问QPS信息,接下来我们在簇点链路中看一下访问链接,并给测试链接添加一条限流规则

阀值类型为QPS,单机阀值这里我们设置为1,代表每秒限定访问一次

点新增后我们再访问一下接口测试一下,测试后发现,如果访问间隔小于1秒,接口返回了限流信息,证明限流生效了
Blocked by Sentinel (flow limiting)
但是实际中这样返回信息不太友好,我们要返回标准的带code和msg的消息体,让和接口返回异常信息保持一致,这样我们就要用到@SentinelResource
@SentinelResource
还是刚刚的接口,我们改造一下,加上@SentinelResource注解
@GetMapping("test")
@SentinelResource(value = "test", blockHandlerClass = CommonBlockHandler.class, blockHandler = "blockHandler")
public RestResult<String> test() {
return RestResult.ok("调用成功");
}
blockHandlerClass代表被block(阻止)时的异常处理类是什么,blockHandler代表block时的处理方法,这里我使用的是异常类的形式,看一下blockHandlerClass是怎么写的
@SuppressWarnings("unused")
public class CommonBlockHandler {
public static RestResult<String> blockHandler(BlockException ex) {
return RestResult.error("服务调用过于频繁");
}
}
这里定义的返回参数类型一定要和接口定义的一致,并且要是静态方法,方法的入参也要保持一致,只不过入参里可以多一个BlockException,方便查看异常
加上注解后再频繁访问一下接口,发现按我们定义的格式返回了异常信息
重启项目后Sentinel的配置可能丢失了,需要重新访问接口后再配置一条限流规则
{"code":-1,"msg":"服务调用过于频繁","data":null}
当然,也可以不用blockHandlerClass这种形式,可以直接在接口同一个类中定义一个异常处理方法,方法也不需要是静态类型,但是当异常类过多后感觉就侵入了业务代码,并且异常处理多了后就显得很臃肿,建议用blockHandlerClass的形式
更多推荐



所有评论(0)