一、介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
二、控制台
2.1 下载jar包
下载客户端:https://github.com/alibaba/Sentinel/releases
2.2 启动控制台
使用java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
命令启动。
其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080。
注意: Sentinel 仅支持 JDK 1.8 或者以上版本。
浏览器输入地址:http://localhost:8080/
Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel
。
三、客户端
控制台已经启动了,现在将客户端接入到控制台
3.1 引入JAR包
<dependencies>
<!--引入 Sentinel 依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.1</version>
</dependency>
<!--Sentinel注解支持 @SentinelResource 注解,注解方式埋点不支持 private 方法。-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.1</version>
</dependency>
<!--客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.1</version>
</dependency>
<!--sentinel整合SpringBoot/Cloud -->
<!-- <dependency>-->
<!-- <groupId>com.alibaba.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>-->
<!-- </dependency>-->
</dependencies>
3.2 定义规则
我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:
- 定义资源
- 定义规则
- 检验规则是否生效
先把可能需要保护的资源定义好(埋点),之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。
在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。
对于主流的框架,我们提供适配,只需要按照适配中的说明配置,Sentinel 就会默认定义提供的服务,方法等为资源。
/**
* 定义规则:
* 通过流控规则来指定允许该资源通过的请求次数,例如下面的代码定义了资源 HelloWorld 每秒最多只能通过 20 个请求。
*/
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
3.3 配置启动参数
sentinel.properties
project.name=SentinelDemo2021-06-1715:02:51
#单个监控日志文件的大小 long 52428800 (50MB)
csp.sentinel.metric.file.single.size=52428800
#监控日志文件的总数上限 默认6
csp.sentinel.metric.file.total.count=2
# 日志默认${user.home}/logs/csp/
csp.sentinel.log.dir=/Users/LiuShihao/IdeaProjects/sentinel-demo/logs
#日志文件名中是否加入进程号,用于单机部署多个应用的情况 默认 boolean false
csp.sentinel.log.use.pid=false
#Record 日志输出的类型,file 代表输出至文件,console 代表输出至终端
csp.sentinel.log.output.type=console
#控制台的地址,指定控制台后客户端会自动向该地址发送心跳包。地址格式为:hostIp:port
csp.sentinel.dashboard.server=localhost:8080
#心跳包发送周期,单位毫秒 long
csp.sentinel.heartbeat.interval.ms=30000
#本地启动 HTTP API Server 的端口号 int 默认为 8719 若端口冲突会自动向下探测可用的端口。
csp.sentinel.api.port=8719
#指定心跳包中本机的 IP
#csp.sentinel.heartbeat.client.ip
3.4 定义资源
/**
* 定义资源
* 资源 是 Sentinel 中的核心概念之一。最常用的资源是我们代码中的 Java 方法。
* 当然,您也可以更灵活的定义你的资源,
* 例如,把需要控制流量的代码用 Sentinel API SphU.entry("HelloWorld") 和 entry.exit() 包围起来即可。
* 在下面的例子中,我们将 System.out.println("hello world"); 作为资源(被保护的逻辑),用 API 包装起来。参考代码如下:
* @param args
*/
public static void main(String[] args) {
// 配置规则.
initFlowRules();
while (true) {
// 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry
try (Entry entry = SphU.entry("HelloWorld")) {
// 被保护的逻辑
System.out.println("hello world");
} catch (BlockException ex) {
// 处理被流控的逻辑
System.out.println("blocked!");
}
}
}
抛出异常的方式定义资源:
SphU
包含了 try-catch
风格的 API。用这种方式,当资源发生了限流之后会抛出 BlockException
。这个时候可以捕捉异常,进行限流之后的逻辑处理。示例代码如下:
// 1.5.0 版本开始可以利用 try-with-resources 特性(使用有限制)
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
try (Entry entry = SphU.entry("resourceName")) {
// 被保护的业务逻辑
// do something here...
} catch (BlockException ex) {
// 资源访问阻止,被限流或被降级
// 在此处进行相应的处理操作
}
特别地,若 entry 的时候传入了热点参数,那么 exit 的时候也一定要带上对应的参数(exit(count, args)),否则可能会有统计错误。这个时候不能使用 try-with-resources 的方式。另外通过 Tracer.trace(ex) 来统计异常信息时,由于 try-with-resources 语法中 catch 调用顺序的问题,会导致无法正确统计异常数,因此统计异常信息时也不能在 try-with-resources 的 catch 块中调用 Tracer.trace(ex)。
3.5 启动客户端
查看控制台页面: