大家好,我是方木
限流一直就是一个比较热门而又老旧的话题,但是作为应对高并发的手段之一,限流的热度一直都在。
提到限流框架,很多人可能会想到Guava
的Ratelimiter
,或者Netflix
的concuurency-limits
,又或者Spring
官方出品的Hystrix
(已经停止维护了)和替代Hystrix的Resilience4j
。
那么,如果必须要我选择一款限流的框架,那就是它 - Sentinel
Sentinel 是面向分布式服务架构的高可用流量防护组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护
等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 2012年诞生,至今已有10个年头,在阿里内部积累了大量的流量生产实践经验。目前的社区活跃度很高,很多公司都在使用。
sentinel的主要功能有
流量控制
:直接限流、冷启动、排队等熔断降级
:通过并发线程数、响应时间进行限制降级系统负载保护
:提供系统维度的自适应保护能力让我们先从简单的例子入手
1. 引入 Sentinel 依赖
使用 Maven引入,在pom.xml
文件中加入sentinel依赖:
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-coreartifactId>
<version>1.8.3version>
dependency>
2. 定义规则和资源
规则
private static void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// QPS 20.
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
资源
public static void main(String[] args) {
// 配置规则
initFlowRules();
while (true) {
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
try (Entry entry = SphU.entry("HelloWorld")) {
// 被保护的逻辑
System.out.println("hello world");
} catch (BlockException ex) {
// 处理被流控的逻辑
System.out.println("blocked!");
}
}
}
也可以直接使用注解
@SentinelResource("HelloWorld")
public void helloWorld() {
// 资源中的逻辑
System.out.println("hello world");
}
3. 运行
可以看到,当我们设置了QPS
为20的时候,SphU.entry()
模拟请求跑了20次就会报错
我们可以查看日志~/logs/csp/${appName}-metrics.log.xxx
,日志中也记录了详情,其中 p
代表通过的请求, block
代表被阻止的请求, s
代表成功执行完成的请求个数, e
代表用户自定义的异常, rt
代表平均响应时长。
可以看到,这个程序每秒稳定输出 "hello world" 20 次
,和规则中预先设定的阈值是一样的。说明sentinel的限流策略生效了。
1646746567000|2022-03-08 21:36:07|HelloWorld|20|6863|20|0|1|0|0|0
1646746568000|2022-03-08 21:36:08|HelloWorld|20|109154|20|0|0|0|0|0
1646746569000|2022-03-08 21:36:09|HelloWorld|20|115142|20|0|0|0|0|0
1646746570000|2022-03-08 21:36:10|HelloWorld|20|134763|20|0|0|0|0|0
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。
Sentinel 控制台包含如下功能:
查看机器列表以及健康情况
:收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线。监控 (单机和集群聚合)
:通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。规则管理和推送
:统一管理推送规则。鉴权
:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。需要注意的是:
Sentinel 控制台目前仅支持单机部署。官方表示Sentinel 控制台不作为开箱即用的生产环境控制台,若希望在生产环境使用要根据文档自行进行定制和改造。
使用sentinel控制台,首先需要下载控制台 jar 包
sentinel 控制台 release 下载页面
ps:也可以自己下载源码打jar包
接着就是启动控制台
java -Dserver.port=8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
访问http://localhost:8080/
就可以看到sentinel的控制台了,默认用户名和密码都是 sentinel
此时控制台空空如也,是因为现在我们的程序是没有接入到dashboard的,
此时我们需要按照以下步骤接入到控制台
引入 Transport
模块来与 Sentinel 控制台进行通信
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-transport-simple-httpartifactId>
<version>1.8.3version>
dependency>
server:
port: 8081
spring:
application:
name: test
cloud:
#sentinel控制台的请求地址
sentinel:
transport:
dashboard: localhost:8080
编写测试接口
@GetMapping("/test")
public String testSentinel() {
String resourceName = "test";
Entry entry = null;
String retVal;
try {
entry = SphU.entry(resourceName, EntryType.IN);
retVal = "passed";
} catch (BlockException e) {
retVal = "blocked";
} finally {
if (entry != null) {
entry.exit();
}
}
return retVal;
}
客户端配置好了与控制台的连接参数之后,并不会主动连接上控制台,需要触发一次客户端的规则才会开始进行初始化,并向控制台发送心跳和客户端规则等信息。所以测试项目启动后访问http://localhost:8081/test
,可以看到,此时的sentinel控制台已经有我们项目启动的信息了
客户端连接上dashboard之后,我们就可以为我们定义的资源配置规则了,有两种方式可以配置规则:
流控规则
页面中新增簇点链路
中添加我们可以在流控规则
页面中新增,点击流控规则
进入页面,如下图所示:
也可以在簇点链路
的页面中找到我们埋点的资源名,然后直接对该资源进行增加流控规则的操作
通过这些资源的配置,就可以简单的实现项目接口的流控了。
以上就是sentinel的基本操作了,后续的文章里方木会继续讲解sentinel的深度使用以及二次开发
,感兴趣的朋友可以点个关注~
欢迎关注我的公众号:Java架构师进阶编程,回复 面试 ,获取上百份面试资源!