一、Sentinel 简介
Spring Cloud Sentinel 是阿里巴巴开源的面向分布式服务、多语言异构化服务架构的流量治理组件。主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
官网地址: https://sentinelguard.io/zh-cn/docs/dashboard.html
二、Sentinel 基本概念
- 资源(Resource):在Sentinel中,任何需要被保护的业务单元都可以被抽象成一个资源。资源可以是一个HTTP请求的URL,也可以是一个Java方法。只要通过 Sentinel API 定义的代码,就是资源,Sentinel 能够对这些资源进行流量控制和熔断降级,就能够被 Sentinel 保护起来。
- 规则(Rule):规则定义了资源在什么情况下应该采取什么样的动作。Sentinel的规则常用的有以下:
- 流量控制规则(Flow Rules):控制资源的QPS或并发线程数。
- 熔断降级规则(Degrade Rules):在调用链上发生故障时,对下游资源进行熔断。
- 系统自适应保护规则(System Rules):监控系统指标,如CPU使用率、系统负载等,当超过阈值时进行保护。
- 控制台(Control Center):Sentinel Dashboard是Sentinel的控制台,用于查看应用的实时流量数据,动态修改规则,实现可视化的流量控制。
- 熔断降级(Circuit Breaking and Degradation):当资源的异常比例超过预设的阈值时,熔断器会打开,后续的调用会被拒绝,经过一段时间的冷却后,熔断器会尝试让一些请求通过,如果这些请求都正常,则熔断器关闭,否则继续保持打开状态。
- 系统自适应保护(System Adaptive Protection):当系统负载过高时,Sentinel可以自动进行保护,防止系统崩溃。
- 热点参数限流(Hotspot Parameter Traffic Control):针对特定的参数值进行流量限制,比如某个商品ID对应的请求量过大时,可以对该商品ID对应的请求进行限流。
三、Sentinel 优缺点
优点:
- 功能丰富:Sentinel 提供了流量控制、熔断降级、系统保护、实时监控等全方位的服务质量保障。
- 易于使用:Sentinel 提供了友好的 Web 界面,可以方便地进行规则的配置和管理。
- 高度可定制:Sentinel 提供了多种 SPI 扩展点,可以根据业务需求进行自定义扩展。
- 开源免费:Sentinel 是完全开源的,可以免费使用。
- 支持多种限流模式:Sentinel 支持直接模式、关联模式、链路模式等多种限流模式,可以根据实际需求选择不同的限流算法。
- 支持多种规则匹配方式:Sentinel 支持精确匹配、子串匹配、正则匹配等多种规则匹配策略,提供灵活的配置选项。
- 支持同步和异步调用:Sentinel 可以方便地支持同步和异步调用,适应不同的应用场景。
缺点:
- 语言多样性支持有限:Sentinel 目前主要支持 Java 应用,对其他编程语言的应用支持不够友好。
- 文档可能略显简单:虽然 Sentinel 的文档已经比较全面,但在一些实践场景中可能存在需要注意的细节。
四、Sentinel 主要功能
4.1 流量控制
(1)Sentinel 进行流量控制主要依赖于流量控制规则(Flow Rules)。流量控制规则允许用户根据预定义的条件(如QPS、线程数等)来限制对某个资源的访问频率,从而避免系统过载。以下是Sentinel进行流量控制的具体步骤:
- 定义资源:首先,需要定义要保护的资源。资源可以是一个接口、方法或者是URL。
- 配置流量控制规则:然后,根据业务需求配置流量控制规则。例如,可以设置平均每秒的请求数(QPS)上限,或者并发线程数上限。
- 规则的加载:配置好的流量控制规则需要加载到Sentinel系统中。可以通过控制台动态推送规则,也可以在应用程序启动时静态加载规则。
- 请求处理:当资源被访问时,Sentinel会实时监测该资源的访问情况。
- 流量控制决策:Sentinel会根据当前的流量情况和流量控制规则来决定是否允许请求通过。如果请求数超过了规则设定的阈值,则部分请求会被阻止,以保证系统的稳定性。
- 规则的动态调整:在系统运行过程中,可以根据实际情况动态调整流量控制规则,以应对流量的变化。
(2)流量控制规则(FlowRule)重要属性如下:
- resource:资源名,资源名是限流规则的作用对象
- grade:限流阈值类型,默认值是1:QPS 模式,0:并发线程数模
- count:限流阈值
- strategy:调用关系限流策略:直接、链路、关联,默认:直接
- limitApp:流控针对的调用来源,默认:default,代表不区分调用来源
- controlBehavior:流控效果(直接拒绝 / 排队等待 / 慢启动模式),默认:直接拒绝
- clusterMode:是否集群限流,默认:否
示例:
private static void initFlowRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
// 设置资源名
rule.setResource("QPS_RULE");
// 设置限流类型为qps
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置每秒qps访问量为1000
rule.setCount(1000);
// 设置不区分调用来源
rule.setLimitApp("default");
rules.add(rule);
// 加载规则到规则管理器
FlowRuleManager.loadRules(rules);
}
4.2 熔断降级
(1)由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。这时熔断机制会切断异常请求,避免故障蔓延,同时提供降级服务以维持系统可用性。Sentinel实现熔断降级主要依靠熔断降级规则和熔断器机制。以下是实现熔断降级的步骤:
- 定义资源:首先,确定需要保护的微服务资源,比如某个API接口。
- 配置熔断降级规则:根据服务的稳定性和业务需求,配置熔断降级规则。这些规则可能包括异常比率、异常数、平均响应时间等指标的阈值。
- 规则的加载:将配置的熔断降级规则加载到Sentinel系统中。规则可以通过Sentinel Dashboard动态配置,也可以在应用程序启动时静态加载。
- 请求处理:当有请求访问被保护的资源时,Sentinel会实时监控该资源的运行情况,包括异常率、异常数和平均响应时间。
- 熔断器状态判断:Sentinel会根据实时监控的数据和熔断降级规则来判断熔断器的状态。常见的状态有:
- 关闭状态(Closed):正常处理请求。
- 半开状态(Half-Open):一段时间后,允许少量请求通过,以检测服务是否已经恢复。
- 打开状态(Open):大部分请求都会被直接拒绝,不继续调用实际服务,以减轻系统压力。
(2)熔断降级规则(DegradeRule)重要属性如下:
- resource:资源名,资源名是限流规则的作用对象
- grade:熔断策略,支持慢调用比例、异常比例和异常数三种类型
- count:阈值,根据不同的grade类型,可以是慢调用临界响应时间、异常比例或异常数量的阈值
- timeWindow:熔断时长,单位为秒,表示在这个时间段内如果触发了熔断条件,服务将被降级
- slowRatioThreshold:慢调用比例阈值,仅在慢调用比例模式下有效,默认5个
- minRequestAmount:熔断触发的最小请求数,如果在统计时间窗内需求数量小于该值,即使异常比率超出阈值也不会触发熔断,默认5个
示例:
private static void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("GRADE_RT");
// 设置熔断策略为慢调用
rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
// 设置慢调用响应时间为:10 ms
rule.setCount(10);
// 设置熔断时长为10s
rule.setTimeWindow(10);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
(3)熔断与降级的区别 :
Sentinel中的熔断(Circuit Breaking)和降级(Degrade)是两种不同的保护机制,它们的目的都是为了提高系统的稳定性和可靠性,但它们的作用和触发条件有所不同。
- 熔断(Circuit Breaking):主要作用是防止系统过载。当某个服务实例的异常率超过一定阈值时,熔断器会自动打开,后续的调用请求将不再调用实际的服务,而是直接返回错误响应,这样可以防止异常继续传播和扩大,保护下游服务。
- 降级(Degrade):降级的主要作用是在系统负载过高时,主动减少系统的服务能力,以避免系统因为资源耗尽而全面瘫痪。当系统负载(如CPU使用率、系统负载等)超过预定阈值时,降级规则会生效,系统会主动拦截部分请求,不去调用实际的服务,而是返回一些预定义的降级响应,如错误码或者默认值。
总结来说,熔断主要是为了防止系统因为服务异常而影响更多的调用者,而降级则是在系统负载过高时主动减少服务能力,两者都是为了保障系统的稳定性,但熔断侧重于异常处理,降级侧重于负载控制。
(4)熔断降级设计理念
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。
- Hystrix 主要通过线程池的方式,来对依赖(在我们的概念中对应资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本,还需要预先给各个资源做线程池大小的分配。
- Sentinel 主要采取了两种手段:
- 通过并发线程数进行限制:和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
- 通过响应时间对资源进行降级:除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
(5)Sentinel 和 Hystrix 的区别
-
设计理念:
- Sentinel:侧重于流量控制、熔断降级和系统负载保护,其设计理念是通过流量作为切入点,保护服务的稳定性。Sentinel提供了更为丰富的流量控制策略,比如QPS限流、线程数限制、系统自适应限流等。
- Hystrix:最初设计用于服务的容错管理,重点在于通过隔离策略(如线程隔离和信号量隔离)来防止服务间的级联失败。虽然Hystrix也提供了断路器功能,但它更关注于单个服务内部的请求隔离和容错。
-
功能特性:
- Sentinel:提供了更细致的流量控制策略,如基于QPS、RT(响应时间)、异常比例的限流规则,以及基于异常比、系统负载的熔断规则。此外,Sentinel还支持热点参数限流、集群流量控制等高级功能。
- Hystrix:主要提供请求缓释(通过线程隔离和信号量隔离)、断路器、请求合并、并发限制等功能。Hystrix的断路器可以防止服务间的级联故障,但它的流量控制能力相对有限。
-
使用场景:
- Sentinel:适合用于流量较大、需要精细化流量控制和系统负载保护的场景,如电商平台的双十一大促活动。
- Hystrix:更适合用于需要服务隔离和容错的场景,特别是当服务需要独立于其他服务进行容错处理时。
-
集成与生态:
- Sentinel:是阿里巴巴推出的开源项目,与Spring Cloud Alibaba等微服务解决方案紧密集成,支持Spring Boot、Dubbo等多种框架。
- Hystrix:最初是Netflix推出的开源库,后来成为了Netflix OSS的一部分,现在已经逐渐被其他更现代的库所替代。
4.3 系统自适应保护
Sentinel的系统自适应保护是一种智能的流量控制机制,从整体维度对应用入口流量进行控制的规则,它们结合了应用的负载(Load)、CPU使用率、总体平均响应时间(RT)、入口QPS和并发线程数等多个监控指标,以实现系统的自适应流量控制。自适应保护规则的目的是在系统稳定的前提下保持系统的最大吞吐量,防止系统被拖垮。
(1)自适应保护规则的触发条件包括:
- Load自适应:适用于Linux/Unix-like系统,当系统负载超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时触发。
- CPU使用率:当系统CPU使用率超过阈值时触发。
- 平均RT:当所有入口流量的平均响应时间达到阈值时触发。
- 入口QPS:当所有入口流量的QPS达到阈值时触发。
- 并发线程数:当所有入口流量的并发线程数达到阈值时触发。
(2)自适应保护规则主要包括以下几个配置属性:
- highestSystemLoad:系统负载触发值,用于触发自适应控制阶段。
- avgRt:所有入口流量的平均响应时间。
- maxThread:入口流量的最大并发数。
- qps:所有入口资源的QPS。
- highestCpuUsage:当前系统的CPU使用率(0.0-1.0)。
示例:
private static void initSystemRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
// 设置系统负载触发值
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}
当系统的这些指标超过预设的阈值时,Sentinel会自动启动保护机制,限制新的请求进入系统,以减轻系统负担。当系统恢复正常后,Sentinel会逐渐恢复流量,直到达到最大吞吐量。这样的自适应调整可以确保系统在高负载情况下不会崩溃,同时又能在负载较轻时充分利用系统资源,提高系统的整体性能和稳定性。
4.4 热点参数限流
Sentinel的热点参数限流是一种针对特定参数的流量控制机制,它能够识别出频繁访问的参数(即热点参数)并对它们实施限流策略,以防止系统因为某个参数的大量访问而受到影响。
在Sentinel中,热点参数是通过LRU(最近最少使用)缓存算法来统计的。Sentinel会记录一定时间范围内出现频率较高的参数,并将这些参数定义为热点参数。一旦某个参数被标记为热点参数,就可以对它应用限流规则。
(1)热点参数限流规则的主要配置属性:
- resource:资源名,指明限流规则适用的服务接口或方法。
- count:限流阈值,即在统计窗口内允许的最大请求次数。
- grade:限流模式,目前仅支持QPS模式。
- durationInSec:统计窗口时间长度,单位为秒,表示在这个时间段内统计请求次数。
- controlBehavior:流控效果,支持快速失败和匀速排队模式。
- maxQueueingTimeMs:最大排队等待时长,仅在匀速排队模式下有效。
- paramIdx:热点参数的索引,对应于资源调用时参数的位置。
- paramFlowItemList:参数例外项列表,可以针对特定的参数值设置单独的限流阈值,不受常规count阈值的限制。
- clusterMode:是否启用集群参数流控规则。
- clusterConfig:集群流控相关配置。
示例:
private static void initParamFlowRule() {
// 创建ParamFlowRule实例
ParamFlowRule rule = new ParamFlowRule("resourceName")
.setParamIdx(0) // 设置热点参数的索引
.setCount(5) // 设置限流阈值
.setDurationInSec(1) // 设置统计窗口时长为1秒
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 设置流控行为为默认值
// 创建ParamFlowItem实例,用于设置参数例外项
ParamFlowItem item = new ParamFlowItem()
.setObject("paramValue") // 设置参数值
.setClassType(String.class.getName()) // 设置参数数据类型
.setCount(10); // 设置针对该值的限流阈值
// 将例外项添加到规则中
rule.setParamFlowItemList(Collections.singletonList(item));
// 加载规则到规则管理器
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
}
4.5 实时监控
Sentinel的实时监控功能允许用户在控制台中查看接入应用的实时流量和运行情况。为了实现实时监控,Sentinel提供了一个名为Sentinel Dashboard的Web应用,用于收集和展示监控数据。Dashboard可以从GitHub上获得,并且需要与Sentinel客户端一起部署。客户端会定期将监控数据推送到Dashboard,Dashboard再对这些数据进行展示和分析。以下是Sentinel实时监控的一些关键特性:
- 流量统计:展示每个资源的实时流量信息,包括QPS(每秒查询次数)、并发用户数、异常数等。
- 异常率:显示每个资源的异常率,帮助用户快速识别出异常高的资源。
- 热点分析:通过热力图展示当前系统中的热点资源,即调用频率最高的资源。
- 端点调用链路追踪:展示服务间调用链路的调用关系,包括调用次数、平均响应时间等。
- 系统负载:展示CPU、内存等系统资源的使用情况。
- 熔断降级情况:展示熔断器的状态,包括已熔断的资源列表及其熔断时长。
- 规则执行情况:展示Sentinel规则的触发情况,包括规则类型、触发次数、参数等。
此外,Sentinel还支持数据的流式传输,即数据在发送到Dashboard之前不会在内存中缓存,这样可以减少延迟并提高监控数据的实时性。为了保证监控数据的准确性和系统的稳定性,Sentinel还提供了数据抽样和限流的机制,防止因为监控数据采集导致的系统压力增大。
4.6 灰度发布
Sentinel本身专注于流量控制、熔断降级等方面的功能,并不直接支持灰度发布。但是,Sentinel可以与其他工具或平台协同工作来实现灰度发布的需求。
灰度发布是一种渐进式发布新版本的策略,它允许新版本的功能只对部分用户开放,而不是一次性对所有用户开放。这种策略有助于降低新版本带来的风险,并可以在小范围内收集反馈,以便及时修复可能存在的问题。要在Sentinel的基础上实现灰度发布,通常需要以下几个步骤:
- 定义灰度规则:在Sentinel中定义灰度规则,可以是基于用户标识、会话信息或者其他业务逻辑来区分流量。
- 服务注册与发现:确保服务实例注册到服务发现组件(如Nacos、Eureka等),这样才能根据流量分配策略将请求导向正确的服务实例。
- 流量控制策略:利用Sentinel的流量控制策略(如QPS限制、异常比例限制等)来实现对灰度流量的控制。
- 灰度路由:结合API网关(如Zuul、Spring Cloud Gateway)或者服务调用框架(如Feign、Ribbon),实现基于规则的灰度路由。当流量到达网关时,根据灰度规则将请求路由到指定的服务版本。
- 监控与反馈:在灰度发布的过程中,持续监控系统的运行状况,收集用户反馈,以便及时调整灰度规则。
五、Sentinel 工作流程
Sentinel 的工作流程主要包括以下几个步骤:
- 规则配置:开发人员根据业务场景配置流量控制、熔断降级等规则,并通过控制台或API方式加载到Sentinel系统中。
- 实时监控:Sentinel持续监控应用的运行状态和流量信息,包括QPS、线程数、异常比例等指标。
- 规则评估:当接收到新的流量请求时,Sentinel会根据当前的运行指标和已配置的规则进行评估。
- 流量控制决策:如果流量超过规则设定的阈值,Sentinel将采取相应的流量控制措施,如限流、降级等,以保护系统不被过载。
- 熔断降级处理:如果服务出现不稳定情况(如响应时间过长或异常率过高),Sentinel将执行熔断策略,暂时切断请求,防止故障蔓延。
- 系统自适应调整:Sentinel支持自适应调整策略,根据系统负载情况动态调整流量控制参数,实现更智能的流量管理。
- 规则动态修改:通过Sentinel控制台,可以动态地添加、修改和删除规则,规则变更后可以实时生效,无需重新部署应用。
- 数据统计与分析:Sentinel会记录相关的流量和异常数据,供后续的数据统计和分析使用,帮助开发人员了解系统运行状况。
- 报警通知:当发生重要事件或规则触发时,Sentinel可以通过邮件、短信等方式向运营人员发送报警通知。
Sentinel 提供了两种运行模式:推送模式(Push Mode)和拉模式(Pull Mode)。
-
推送模式:
- Sentinel 客户端会定期主动将监控数据(如调用次数、错误率等指标)推送到Sentinel 控制台(Sentinel Dashboard)。
- 控制台接收到数据后进行聚合和分析,用于展示监控数据、生成规则等。
- 这种模式适用于数据量不大且客户端可以频繁与控制台通信的场景。
-
拉模式:
- Sentinel 控制台主动向Sentinel 客户端发起请求,拉取客户端的监控数据。
- 客户端响应请求,将当前的监控数据发送给控制台。
- 控制台根据拉取到的数据进行处理和展示。
- 这种模式适用于客户端不方便频繁发送数据,或者数据量较大的场景。