Sentinel学习

(1) 什么是Sentinel

Sentinel介绍

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。

Sentinel架构

Sentinel 具有以下特征:

  1. 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  2. 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  3. 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要3引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  4. 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel特征

(1.1) Sentinel有哪些功能

Sentinel提供了流量控制熔断降级系统负载保护 等功能

(1.1.1) 流量控制

流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。
然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:

流量控制

流量控制有以下几个角度:
资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
运行指标,例如 QPS、线程池、系统负载等;
控制的效果,例如直接限流、冷启动、排队等。
Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。

(1.1.2) 熔断降级

除了流量控制以外,降低调用链路中的不稳定资源也是 Sentinel 的使命之一。由于调用关系的复杂性,如果调用链路中的某个资源出现了不稳定,最终会导致请求发生堆积。这个问题和 Hystrix 里面描述的问题是一样的。

熔断

Sentinel 和 Hystrix 的原则是一致的: 当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。

(1.1.3) 系统负载保护

Sentinel 同时提供系统维度的自适应保护能力。防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。

负载保护

针对这个情况,Sentinel 提供了对应的保护机制,让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求。

系统自适应保护


(2) 为什么要用Sentinel

(2.1) Sentinel解决的问题

稳定性
1、限流
2、熔断降级

(2.2) 功能对比

Guideline: 从 Hystrix 迁移到 Sentinel

(2.2.1) Sentinel-Hystrix-resilience4j-功能对比

Sentinel Hystrix resilience4j
隔离策略 信号量隔离(并发线程数限流) 线程池隔离/信号量隔离 信号量隔离
熔断降级策略 基于响应时间、异常比率、异常数 基于异常比率 基于异常比率、响应时间
实时统计实现 滑动窗口(LeapArray) 滑动窗口(基于 RxJava) Ring Bit Buffer
动态规则配置 支持多种数据源 支持多种数据源 有限支持
扩展性 多个扩展点 插件的形式 接口的形式
基于注解的支持 支持 支持 支持
限流 基于 QPS,支持基于调用关系的限流 有限的支持 Rate Limiter
流量整形 支持预热模式、匀速器模式、预热排队模式 不支持 简单的 Rate Limiter 模式
系统自适应保护 支持 不支持 不支持
控制台 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 简单的监控查看 不提供控制台,可对接其它监控系统

(2.2.2) 线程池隔离

线程池隔离的好处是隔离度比较高,可以针对某个资源的线程池去进行处理而不影响其它资源,但是代价就是线程数目比较多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。
另外,托管的线程切换可能会导致基于 ThreadLocal 的上下文传递丢失的问题(如 Spring 事务管理)。
Sentinel 没有提供线程池隔离这样比较重的隔离方式,而是提供了信号量隔离这种比较轻量级的隔离方式。

(2.2.3) 信号量隔离

信号量隔离是作为流量控制的一种模式


(3) Sentinel是怎么设计的

(3.1) Sentinel 基本概念

// todo

资源(Resource)
资源是 Sentinel 的关键概念。它可以是应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

规则(Rule)
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

节点(Node)

功能插槽(Solt)

上下文(Context)

实体(Entry)


(4) Sentinel原理

Sentinel工作主流程

在 Sentinel 里面,所有的资源都对应一个资源名称以及一个 Entry。
Entry 可以通过对主流框架的适配自动创建,也可以通过注解的方式或调用 API 显式创建;
每一个 Entry 创建的时候,同时也会创建一系列功能插槽(slot chain)。

这些插槽有不同的职责,例如:

处理插槽 作用 备注
NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来 用于根据调用路径来限流降级
ClusterBuilderSlot 负责维护资源运行统计信息(响应时间、qps、线程数、异常),以及调用者列表 这些信息将用作为多维度限流,降级的依据
LogSlot 记录(BlockException)异常日志 (限流、熔断)
StatisticSlot 用于记录、统计不同纬度的 runtime 指标监控信息;
AuthoritySlot 根据配置的黑白名单和调用来源信息,来做黑白名单控制;
SystemSlot 通过系统的状态,例如 load1 等,来控制总的入口流量;
FlowSlot 用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
DegradeSlot 通过统计信息以及预设的规则,来做熔断降级;

Sentinel核心类解析

Sentinel 的核心骨架,将不同的 Slot 按照顺序串在一起(责任链模式),从而将不同的功能(限流、降级、系统保护)组合在一起。
slot chain 其实可以分为两部分:统计数据构建部分(statistic)和判断部分(rule checking)。

核心结构:
Sentinel架构


参考资料

[1] Sentinel介绍-官网
[2] Sentienl ReadMe-github