0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

开源分析和落地方案—Sentinel篇

京东云 来源:京东物流 刘达 作者:京东物流 刘达 2024-11-08 10:10 次阅读

作者:京东物流 刘达

一、Sentinel是什么?

Sentinel是从阿里技术体系内诞生并由相关社区从微服务到云原生阶段持续孵化的流量治理组件,在服务熔断限流以及秒级/分钟级监控方面提供了开箱即用的解决方案,此外作为支持云原生的重要探索,还提供了GO语言实现。Sentinel目前拥有着活跃的开源社区,从1.8.x版本开始,通过深度参与到SpringCloudAlibaba套件的支持,实现与Java主流开发框架SpringBoot及SpringCloud的兼容,进而成为了Java技术栈开源熔断限流的事实标准。虽然其2.x版本持续难产(可能是适配OpenSergo规范的影响),不过好在1.8.x并没停止迭代,今年以来已经在1.8.7(JDK8)的基础之上做了1.8.8(JDK17)的升级,完成了主流JDK版本的支持,基本能够满足Javaer的开发需求。

考虑到一般部署环境以JDK8居多,而且1.8.8除了JDK的升级外,没有做实质的功能改造,所以本篇文章主要基于1.8.7版本展开,即在JDK8的环境下对Sentinel的能力进行讨论。

二、Sentinel能带来什么?

就如前文所介绍的,Sentinel提供了完善的熔断、限流以及秒级/分钟级监控方案。最核心的一点,就是它把应用规则的目标统一抽象成了一个概念——资源。按照官方说明,资源可以是Java应用程序中的任何内容,比如服务、接口方法或者一段代码。只要用Sentinel提供的资源创建及释放API包裹起来,就可以称之为一个资源。资源的抽象为Sentinel的使用提供了极大的灵活性,这让开发者可以把代码链路中的任何一个部分都做到流量治理规则中,当然为了提高代码的可读性以及规范性,我们还是推荐以服务入口(HttpRPC)、接口或者接口的实现方法作为最小资源单元。

同时,Sentinel提供了丰富的控制规则:

▪流量控制(FlowRule)

区分来源、限流类型(QPS/线程数)、支持上下游链路、多种流控效果(拒绝、排队、慢启动)

▪热点参数限流(ParamFlowRule)

热点限流是对流量控制的补充,对Top-K的热点参数进行限流处理

▪系统负载限流(SystemRule)

可以理解为应用级的流量控制策略,包含负载、单机平均RT,单机QPS等。不过,因为粒度较粗且部分指标的获取在容器环境下存在适配问题,所以社区中大部分人对这个的理解是还有待完善,成熟的案例比较少。

▪熔断降级(DegradeRule)

在熔断降级方面,则是直接对标的Hystrix框架,一是在实现机制上做了优化,相对Hystrix基于线程池的隔离控制策略,通过并发控制机制减少了线程池的创建和占用。另外,在配置上也更加简化,相信有过Hystrix使用经验,都会对其繁杂的注解配置项感到困惑,而当引入Sentinel时则无需担心这些。

如果仅仅是这些,Sentinel的定位也仅限于一个组件包,类似Hystrix一样。那为何本文开篇说Sentinel是一套解决方案呢?因为它还做到了另外的三点,接下来继续进行说明:

第一点:包容性

Sentinel通过对Adapter模块组持续迭代,目前已经兼容了主流的一系列调用协议及组件,比如dubbo2,dubbo3,httpclient,okhttp,grpc,sofa,quarkus,webflux,webmvc等。此外还完成了对Java开源网关的支持,包括zuul1,zuul2,springcloud-gateway。并且作为java应用流量控制的标准框架,很多其他开源框架也在项目内部做了相关的兼容。

第二点:界面化

Sentinel提供了方便易用的Dashboard,支持常用的一系列操作。比如应用的注册发现,规则参数的配置、查看,接口簇点链路的自发现和树状展示,秒级的监控视图等等,虽然开源方案展示的数据以内存或者对应用节点信息的拉取为依托,但这已经提供了非常强的指导性。其对应的商业化版本AHAS已经在阿里云中得到广泛应用。

第三点:扩展性

虽然core包提供的是基于应用内存的数据存取策略,但是sentinel同时对控制规则数据的拉取链路做了通用的抽象,并衍生出了一系列datasource包。包含apollo、consul、etcd、nacos、redis、zk等,他们具备的共同点就是客户端能够及时的获取到配置数据变更事件,而Sentinel依赖的控制规则就是以配置数据的形式维护在这些中间件中,并实现对客户端的分发。

前文介绍了这么多,那引入Sentinel能带来什么改变呢?

我觉得,首先,限流策略更加丰富,能够更好的应对日趋复杂的限流需求;其次,对于资源的流量管理实现了统一,从单一入口维护应用的所有流量控制规则,无需从网关、JSF等分别对应用的入口进行配置;限流的维度更加细化,从入口级下沉到了应用内资源;在熔断的支持上,除了JSF客户端调用外,应用内部或作为客户端对外部的任何协议调用都可以增加熔断的管理,服务的稳定性也会随之提升。

三、Sentinel的重点实现

概念之后再来说说Sentinel中的关键实现。这一部分准备分三块来说明。第一是它的核心规则控制链路,第二它的datasource实现结构,第三Dashboard与应用的交互逻辑。此处主要是专注在架构实现上,像业内熟知的一些控制算法比如令牌桶等,不再赘述。

1、核心规则控制链路

为了更好的理解这条链路的结构,此处引入一下官方图

wKgZomctcvGAJgnIAANxGK8Ho6s851.png



上图即Sentinel的默认ProcessorSlotChain所配置的链路结构,默认实现依托DefaultProcessorSlotChain。

wKgaomctcvOAIqqfAAFqO8xZ0dU513.png



从代码上看是一个标准的链表结构,链表中装配的节点对象类型为AbstractLinkedProcessorSlot,也就是图中这些Slot的父类,我们或可以称之为Slot模版类。通过代码的查看,会发现它声明了两个方法,entry、exit分别作为Slot的入口和出口,并且在方法入参中携带了当前调用链路的上下文信息。通过官方图例能够看出,请求在进入处理链条后,按先后顺序会经过三类Slot,前置的NodeSelectorSlot、ClusterBuilderSlot用于调用链路的提取,中间StatisticSlot是通用的滑动窗口计数功能,比如RT、通过数、拒绝数、异常数等,后置的ParamFlowSlot、SystemSlot等则为真正的规则验证链条。如下图所示,

wKgZomctcvSAa0amAAERRjGnlXg894.jpg



在上图中,会发现在模版类中有额外的两个方法,fireEntry和fireExit,这两个方法在AbstractLinkedProcessSlot中均有默认的实现,主要是用于在当前节点entry或exit方法执行过程中触发对next节点的调度,这就使得Slot链表触发顺序和完成顺序并不一定相同。这样的好处是在基础链路上提供了充足的灵活性,上游Slot可以按需触发下游Slot并获取执行结果。例如此处用于统计计数的StatisticSlot和用于规则验证的一系列Slot列表之前的关系,正常通过和规则拦截的调用都能被StatisticSlot抓取到进行统计。

2、Datasource实现

作为配置文件的读取来源,Sentinel提供了标准实现框架,并以此为基础,对主流的开源分布式配置中心也做了充分的适配,还是以类结构图作为切入点

wKgaomctcvSAH4H3AAFOhPzf5eE411.jpg



可以看到,Sentinel提供的Datasource规范中,通过loadConfig,readSource,getProperty,close四个方法,覆盖了数据源的读取、加载、查询和释放整个流程。落地到具体实现方案,它提供了两个大的方向,前者是支持热更新,后者是不可变的配置来源,如jar包中的文件。

热更新模式下,基于数据源的特性,又细分了两种,我把它总结为轮询模式和订阅模式。像Eureka、本地文件这种,不支持数据变更事件的订阅,Sentinel提供的方案是按照一定的时间间隔,定期的去拉取最新数据比对是否需要更新,这种就是前面讲的轮询模式。还有一种,依托于越来越成熟的各种开源分布式配置中间件,应用通过SDK集成,能够方便的订阅指定的配置项,并实时接收数据变更事件进行处理逻辑,相对于轮询模式配置生效的更加及时,是目前线上案例中最常用的模式。

对于不可变模式,Sentinel也仅提供了一种实现,仅限于无配置变更需求的场景,支持一次性加载,好处是轻量依赖项少,但更新需要重启。

3、Dashboard与应用的交互

核心链路和数据来源之后,再来说说Sentinel关于控制面的实现。

首先,要说明的是,即便是到最新的版本,Sentinel Dashboard也不是必须的。尤其是在1.6.x以前,datasource和dashboard这些模块都还未完善,项目引用Sentinel的方式主要是以硬编码为主,控制规则是借助RuleManager的静态方法进行初始化,调用链路中通过SphU或SphO实现资源的创建,使用Tracer去显式的记录异常(@SentinelResource是在1.8.x才趋于完善)。现在,官方文档在大部分基础用例中也是以这些形式为主。那Dashboard的作用是什么?

Dashboard为我们提供了相对完整的控制面,基本涵盖了Sentinel的所有功能,包含各种规则的查看和配置、节点的自动注册发现以及健康状态监控、簇点链路的采集等,在可观测方面提供了秒级的监控视图,而在后台为这些功能的数据提供了基于内存的实现,为我们实现硬编码到控制台的转变提供了明确的方向。接下来从三个角度说明Dashboard的重点实现,分别是节点信息的发现、规则数据的维护、秒级监控的采集。逻辑链路如下所示:

wKgZomctcvWAYjPdAADwZVfQZUE005.jpg

这张链路图基本把Sentinel从客户端到Dashboard服务端的交互过程做了明确的展示。

A. 首先,Sentinel控制台对客户端的发现机制并不依赖于其他中间件,是独立的相对轻量的实现。逻辑上很简单,即在控制台暴露了一个MachineRegistryController,客户端配置Dashboard地址后,定时的上报心跳数据。

B. Sentinel对应用的Metrics数据采集是以定时拉取的方式,应用SDK会暴露http入口,用于提供给Dashboard服务侧进行调用。Dashboard中相关的规则配置也是以类似的方式进行,额外增加了数据的写入动作用于更新规则。

C. sentinel-core本身对Dashboard侧的交互没有依赖,而是通过transport包中以集成Spiloader的方式追加相关的初始化动作,实现像注册心跳、远端控制等附加能力,即sentinel-core仍然是独立可用的。

SlotChain、Dashboard和Datasource是一套组合拳,共同构成了Sentinel的流控解决方案。SlotChain完成了核心的规则控制逻辑,而Datasource则是解决了配置数据怎么更新怎么同步的问题,最后Dashboard则是将配置数据的界面化维护以及运行时数据的展示入口提供给了开发者,让线上的落地成为了可能。



四、Sentinel源码包结构

从工程结构上看,Sentinel以sentinel-core为基础,衍生了一系列的模块:

1、sentinel-dashboard:sentinel控制台,提供简易的登录方式,功能上支持节点注册展示,限流、熔断等流控规则的查看与下发,节点Metric信息的采集和聚合展示等。

2、sentinel-transport:内部通信模块,实现客户端节点的心跳注册以及消息接收功能。

3、sentinel-logging:sentinel为了和应用日志做隔离,单独指定的日志输出问题,这个模块提供了基于slf4j的默认实现,同时可以作为参考实现,以SPI的方式定制其他日志输出通道。

4、sentinel-adapter:协议适配模块,基本兼容了所有开源的协议,一是在资源生成时指定prefix,另外就是依赖调用链路中的FiIter做协议解析,以支持抽取流控规则依赖的参数,比如origin等。

5、sentinel-extension:这个模块组则是作为一版扩展实现,不过大部分主要是依赖各种分布式配置型中间件实现的datasource模块,实现规则数据的存取。

6、sentinel-cluster:主要是提供集群限流的部分简易实现,目前看这种基于token分发中心的集群限流方案在性能上损耗相对单机型还是要大一些。



五、Sentinel的落地问题及改造方案

在上文中,对Sentinel的逻辑架构以及源码已经做了详细介绍。如果在我们生产环境中落地,有哪些问题?

我们知道,Sentinel提供的默认实现,数据的读取以内存为主要媒介。Dashboard基于节点上报的心跳信息做汇总,收集到AppManagement中,用于左侧菜单栏的应用展示,并开始根据心跳上传时间判断各应用内节点的在线离线状态,当单个应用内所有节点都离线就对该应用进行隐藏。规则数据的读取以及Metric统计信息是通过远程调用节点的通信入口进行。由此可以衍生出下面四个场景的落地方案:

1、规则数据的读写

在第三部分中也介绍到,Sentinel对于规则数据的同步机制,提供了一组datasource模块,主要以各分布式配置中间件为中心,实现数据的写入和变更监听,达到动态变更规则数据的目的。如果开发者并不想引入这些额外的中间件,那么就需要根据自己的需求来扩展datasource模块。

接入新的配置源,首先从Dashboard开始,我们可以参考FlowControllerV2中提供的Nacos配置样例,对应于各个规则,实现基于appName的DynamicRuleProvider和DynamicRulePublisher的读写入口类,将规则数据以Json的形式写入新的配置源中,当然为了更大的扩展性和业务隔离性,我们可以在appName的参数基础上,再追加类似Datacenter这种参数,以区分不同的业务群,避免单个Dashboard中应用过量造成处理压力。

另外,就要考虑sentinel-datasource-{CustomizedDatasource}的开发,基于sentinel-datasource-extension这个数据源监听模版,参考sentinel-datasource-nacos中NacosDataSource实现对应的AbstractDataSource,到此为止只是实现了Datasource类的定义和实现。而真正打通Dashboard到节点侧的数据链路,还需要对Datasource的调用和初始化流程。Sentinel包中的demo工程,有针对于各个datasource的初始化样例。

而我们如果想真正落地到项目中,仅仅这些还是不够的,而是需要把Datasource对各个规则的加载和监听封装成独立的Starter,这样才能最大限度降低springboot集成的复杂度。对于这个想法,我们则需要转向另一个开源项目:spring-cloud-alibaba-sentinel-datasource和spring-cloud-starter-alibaba-sentinel。

前者将不同Datasource和对应的配置节点做了关联,如下

①DatasourceFactoryBean的声明

public class NacosDataSourceFactoryBean implements FactoryBean< NacosDataSource >

②Properties初始化参数中携带对应的FactoryBean

public NacosDataSourceProperties() {    super(NacosDataSourceFactoryBean.class.getName());}

后者,则是在初始化SentinelDataSourceHandler的过程中,根据SentinelProperties中各Datasource子节点配置与否决定是否初始化到Bean实例,如下

wKgaomctcviAdDd3AAOgNOH3PME322.png



通过这几部分的构建,我们就可以实现自己的Sentinel-Starter,实现基于自定义数据源做规则数据的运维。



2、Metric统计数据及日志的托管

目前Metric信息是采用从Dashboard定时拉取再从应用维度聚合的方式进行。节点中的Metrics信息是相对完整的,我们可以从两方面来进行收集:

第一种方式,节点主动上报,收集至统一的存储,再以Grafana的形式做数据展示。具体方式的话,可以选用直接上传到定制的OAP服务,也可以扩展sentinel-log模块的实现做基于日志的上传(因为sentinel的设计机制中,自身的状态日志和业务日志是分离的)。不过,这会造成一定的性能损耗,落地到项目中需要进行详细的压测和评估。

第二种方式,由中控进行定时采样,时间间隔可以自定义,也就是以拉的方式进行,采样率可以在中控进行统一的动态控制,合理配置能够更容易达到性能损耗和观测性的平衡。

此处不再细说,方案比较多,见仁见智。



3、Dashboard的适配

Dashboard面向线上业务场景,需要解决的有以下三点:

①数据存储问题:上文中规则数据的Datasource扩展不再讨论,除此以外,Sentinel中节点、应用、簇点链路都是基于内存存储的,这就有一个问题——重启丢失。因为这些信息都是基于节点心跳的,数据丢失后意味着重新收集,那么之前在这些数据上做的规则配置就会丢失查看的入口。另外,应用的展示是以应用内节点的在线状态为准的,当应用内所有节点都离线,也会造成应用列表中缺失。所以解决方案就是需要将应用、节点保存至持久化存储中,例如Mysql,而簇点链路信息由于树状结构的特殊性,可以直接放到Redis中存储以及更新。

②权限问题:Dashboard通过轻量的自定义Filter实现的最简单的登录控制。落地的话就需要首先接入ERP统一登录,另外还需要做应用权限的管理,避免权限穿透和误操作问题。

③业务划分:需要按照业务进行应用层面的划分。实现多数据中心的支持,避免中心节点集成应用过多。



4、协议的适配

相比前几点,此处的改动是最轻量的。当开发使用的调用协议不在Sentinel官方兼容,那么就需要对协议做适配性开发。按照sentinel-adapter中对其他协议的适配方式,我们需要改造的大体可以总结为两点,第一,常规调用上下文参数的解析,比如调用来源等;第二,定义协议入口的资源前缀,与其他资源做区分。

六、小结

本文围绕Sentinel展开,从其基本概念到核心实现,再到探讨开源方案的挑战和如何在实际项目中应用和改进Sentinel。Sentinel以其高度的灵活性和可扩展性赢得了广大开发者的青睐,不论是新系统的开发还是现有系统的维护,Sentinel都能为我们提供极具价值的支持。



参考内容:

【1】https://sentinelguard.io/zh-cn/

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    3007

    浏览量

    73916
  • 开源
    +关注

    关注

    3

    文章

    3260

    浏览量

    42431
  • JDK
    JDK
    +关注

    关注

    0

    文章

    81

    浏览量

    16580
  • Sentinel
    +关注

    关注

    0

    文章

    10

    浏览量

    7143
收藏 人收藏

    评论

    相关推荐

    Sentinel扩展性设计机制分析

    Sentinel 提供多样的 SPI 接口用于提供扩展的能力。用户可以在用同一个 sentinel-core 的基础上自行扩展接口实现,从而可以方便地给 Sentinel 添加自定义的逻辑。 初始化
    的头像 发表于 10-26 10:03 4134次阅读

    基于Sentinel自研组件的系统限流、降级、负载保护最佳实践探索

    一、Sentinel简介 Sentinel 以流量为切入点,从 流量控制 、 熔断降级 、 系统负载 保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: • 丰富的应用场
    的头像 发表于 09-25 11:19 1270次阅读
    基于<b class='flag-5'>Sentinel</b>自研组件的系统限流、降级、负载保护最佳实践探索

    晶丰明源落地方案MCU+MOS方案应用

    晶丰明源落地方案应用
    发表于 04-10 19:02

    华秋 BLDC 专区上线!为您汇集基于各品牌 MCU 落地应用的相关 BLDC 方案

    、风扇吊扇、卷发棒、高速风筒等可量产的全套解决方案,华秋商城现已开辟 BLDC 专区,电机控制解决方案商正火热招募中,欢迎登录华秋商城查看!这里先为大家整合了部分基于各 MCU 落地应用的相关 BLDC
    发表于 06-20 15:28

    开源图形驱动在OpenHarmony上的使用和落地

    本文转载自 OpenHarmony TSC 官方《峰会回顾第10期 | 开源图形驱动在OpenHarmony上的使用和落地》 演讲嘉宾 | 黄然 回顾整理 | 廖涛 排版校对 | 李萍萍 嘉宾简介
    发表于 08-31 18:07

    LEM发布综合电池监测器件Sentinel III

    LEM发布综合电池监测器件Sentinel III 莱姆(LEM)近日发布了一款先进的综合电池监测方案Sentinel III,该款解决方案解决了不间断电源(UPS)原始设备制造商(
    发表于 11-25 09:15 652次阅读

    莱姆电子推出新一代Sentinel产品Sentinel 3+

    LEM莱姆电子宣布推出经过验证的新一代Sentinel 产品Sentinel 3+,可对不间断电源(UPS) 系统中的后备电池健康状态进行连续监测
    发表于 04-08 10:10 1327次阅读

    阿里巴巴宣布 Sentinel 开源,进一步完善 Dubbo 生态

    对外开源的,目的是帮助开发者获得更完整的分布式服务解决方案。例如当我们限流的流量发生变化的时候,我们需要迅速推规则的时候,Sentinel可以和Nacos相互整合,起到快速操作、快速配送的效果
    发表于 08-14 17:32 211次阅读

    Sentinel 如何通过匀速请求和冷启动来保障服务的稳定性

    摘要: 这是围绕 Sentinel 的使用场景、技术对比和实现、开发者实践等维度推出的系列文章的第二。 第一:Dubbo 的流量防卫兵 | Sentinel如何通过限流实现服务的高
    发表于 08-28 14:09 326次阅读

    [开源] DSLogic开源逻辑分析方案分享

    今天来分享一个开源的项目——DSLogic,它是一款基于FPGA的逻辑分析仪,是由国内的梦源实验室(DreamSourceLab)做出的开源软硬件产品,从...
    发表于 01-26 18:17 50次下载
    [<b class='flag-5'>开源</b>] DSLogic<b class='flag-5'>开源</b>逻辑<b class='flag-5'>分析</b>仪<b class='flag-5'>方案</b>分享

    Sentinel高可用流量管理框架

    Sentinel.zip
    发表于 04-25 09:24 0次下载
    <b class='flag-5'>Sentinel</b>高可用流量管理框架

    开源鸿蒙OpenHarmony在电力行业首次落地

    开源鸿蒙OpenHarmony在电力行业首次落地 开放原子开源基金会拟于2023年6月举办“2023开放原子全球开源峰会(OAGS)”。6 月 12 日,以“OpenHarmony 共
    的头像 发表于 06-09 19:30 1976次阅读

    AI Codec在应用落地方面的案例

    ),展现了强大的技术潜力。但受限于计算复杂度、非标等原因,AI Codec在应用落地方面的案例却屈指可数。LiveVideoStackCon2022北京站邀请了来自双深科技的田康为大家分享基于双深
    的头像 发表于 06-19 09:50 857次阅读
    AI Codec在应用<b class='flag-5'>落地方</b>面的案例

    EMC案例分析:不同接地方案对EFT/B测试的影响

    前面我们介绍过《EMC的三大法宝之一:接地》和《EMC的三大法宝之一:接地(二)》,本次我们就不同接地方案对EFT/B测试的影响进行举例分析
    的头像 发表于 09-07 09:59 1201次阅读
    EMC案例<b class='flag-5'>分析</b>:不同接<b class='flag-5'>地方案</b>对EFT/B测试的影响

    基于Sentinel实现历史监控数据回看

    众所周知,Sentinel 对监控数据的做法是定时落盘在客户端,然后 Sentinel 提供接口去拉取日志文件。
    的头像 发表于 11-27 14:34 837次阅读
    基于<b class='flag-5'>Sentinel</b>实现历史监控数据回看