前言
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性
- Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案.
- Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性.
Sentinel的功能
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。
然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。
任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。
我们需要根据系统的处理能力对流量进行控制。
Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:
-
限流方式
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系
- 运行指标,例如 QPS、线程池、系统负载等
- 控制的效果,例如直接限流、冷启动、排队等
熔断, 服务降级
由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积, 最终拖垮整条链路.
降低调用链路中的不稳定资源也是 Sentinel 的使命之一(和Hydrix类似)
Sentinel进行熔断的方式:
- 限制并发线程数
- 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。
- 这样不但没有线程切换的损耗,也不需要预先分配线程池的大小。
- 当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。
- 当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。
- 堆积的线程完成任务后才开始继续接收请求
- 通过响应时间对服务进行降级
- 当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复
系统负载保护
Sentinel 同时提供系统维度的自适应保护能力。
防止雪崩,是系统防护中重要的一环。
当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。
在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。
如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。
Sentinel的基本工作机制
- 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析
- 根据预设的规则,结合对资源的实时统计信息,对流量进行控制, 同时Sentinel 提供开放的接口,方便定义及改变规则
- Sentinel 提供实时的监控系统,方便快速了解目前系统的状态
在 Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry.
Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建.
每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain), 这些插槽有不同的职责,例如:
- NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
- ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
- StatisticSlot 核心功能之一, 用于记录、统计不同纬度的 runtime 指标监控信息;
- FlowSlot 则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
- AuthoritySlot 则根据配置的黑白名单和调用来源信息,来做黑白名单控制.
- DegradeSlot 主要针对资源的平均响应时间(RT)以及异常比率,来决定资源是否在接下来的时间被自动熔断掉.
- SystemSlot 根据对于当前系统的整体情况,对入口资源的调用进行动态调配。其原理是让入口的流量和当前系统的预计容量达到一个动态平衡.
Sentinel的使用
Sentinel 的使用可以分为两个部分:
-
核心库(Java 客户端):
不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持. -
控制台(Dashboard):
Dashboard 主要负责管理推送规则、监控、管理机器信息等.
核心库
1. 引入 Sentinel 依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
2. 定义资源
资源 是 Sentinel 中的核心概念之一.
最常用的资源是我们代码中的 Java 方法.
把需要控制流量的代码用 Sentinel API SphU.entry("HelloWorld") 和 entry.exit() 包围起来即可
public static void main(String[] args) {
// 配置规则.
initFlowRules();
while (true) {
try (Entry entry = SphU.entry("HelloWorld")) {
// 被保护的逻辑
System.out.println("hello world");
} catch (BlockException ex) {
// 处理被流控的逻辑
System.out.println("blocked!");
}
}
}
3. 定义规则
通过流控规则来指定允许该资源通过的请求次数
private static void initFlowRules(){
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 每秒请求次数限制为20
rule.setCount(20);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
Sentinel控制台
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能
- 查看机器列表以及健康情况:
收集 Sentinel 客户端发送的心跳包,用于判断机器是否在线 - 监控 (单机和集群聚合):
通过 Sentinel 客户端暴露的监控 API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控 - 规则管理和推送:
统一管理推送规则
下载Sentinel控制台jar包或者从源代码自行构建: https://github.com/alibaba/Sentinel/releases
1. 启动控制台
控制台地址默认为http://localhost:8080/
默认账号密码为sentinel
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
2. 客户端接入控制台
客户端需要引入 Transport 模块来与 Sentinel 控制台进行通信
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>x.y.z</version>
</dependency>
客户端启动时加入 JVM 参数 -Dcsp.sentinel.dashboard.server=consoleIp:port
指定控制台地址和端口
待客户端触发请求后, 在Sentinel控制台页面会初始化此客户端应用, 并开始向控制台发送心跳包
- 根据适配的框架不同, 客户端接入控制台的方式也不同, 如适配SpringCloud框架:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
且在Spring配置文件中配置Sentinel控制台信息以及使用哪个端口与控制台进行交互:
spring:
cloud:
sentinel:
transport:
# 如果8719端口冲突, 会自动向下探测可用端口
port: 8719
dashboard: localhost:8080
3. 查看机器列表以及监控状况
待应用在Sentinel控制台初始化后, 可以在看到应用所在机器列表以及机器状态
4. 实时监控
- 多次发起调用, 在Sentinel DashBoard控制台对应的服务中点击实时监控, 可以看到当前被调用的接口的实时QPS, 请求成功率以及响应时间等
- 同一个服务下的所有机器5分钟内的簇点信息被汇总显示, 有相关API支持获取监控数据进行持久化
5. 规则管理以及规则推送
在核心库中需要编写规则对资源调度进行限流, 而在Sentinel控制台可以进行可视化配置
此过程的规则推送是通过相关API与应用内进行交互, 属于内存态, 一旦应用重启就会失效
-
原始推送模式
API 将规则推送至客户端并直接更新到内存中,扩展写数据源- 优点: 简单,无任何依赖
- 缺点: 不保证一致性;规则保存在内存中,重启即消失
-
Pull模式
扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件等- 优点: 简单,无任何依赖;规则持久化
- 缺点: 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题
-
Push模式
扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源- 优点: 规则持久化;一致性;快速
- 缺点: 引入第三方依赖