作积极的人,越努力越幸运!
在介绍集群限流以前须要首先掌握动态数据源的配置方式,本文将根据 Sentinel 官方提供的代码提出总体架构思路,并最终给出实践指导。redis
舒适提示:本文主要分为动态数据源架构设计理念、从官方示例寻找改造思路、基于SpringBoot改造方案三个部分来详细剖析 Sentienl 动态数据源的改造方案,按部就班,不只解决问题自己,更是反映了做者研究一个问题的思路与方法。spring
在 Sentinel 中主要有以下几个角色:管理后台、限流熔断规则数据源、应用程序。数据库
1)管理后台编程
管理后台主要用于可视化配置限流规则、熔断规则,其操做界面截图以下:json
2)限流熔断规则数据源
用于存储限流熔断规则的数据容器,在 Sentinel 中对应动态数据源这个概念,动态数据源包含两层含义:架构
数据容器
数据容器指的就是存储熔断、限流等规则配置的数据库,例如关系型数据库、Zookeeper等等,在实际生产过程当中须要选用支持持久化功能的数据库,不然程序一重启,配置规则就会丢失,显然是不能接受的。app
但愿经过 Sentinel 提供的限流、熔断功能对应用程序加以保护,须要引用 Sentinel 相关的 SDK,根据采集的调用信息判断当前是否符合限流规则。ide
后台管理系统、动态数据源、应用程序的关系如图所示:测试
从官方的文档中能够明确获悉 sentinel-dashboard 即官方自带的后台管理系统只支持将限流、熔断等限流配置规则存储在内存中,一旦后台管理系统重启,配置的熔断规则将所有丢失,因此在生产实践过程当中须要对 sentinel-dashboard 进行必定的改造,引入动态数据源,例如 Zookeeper,对限流等配置进行持久化存储。架构设计
有了上面的架构设计理念为咱们的改造提供了方向,那如何具体改造呢?首先咱们来看一下官方提供的 Demo 程序。官方提供的示例代码以下图所示:
接下来咱们将以 zookeeper 动态数据源来介绍基于 zookeeper 如何构建 Sentinel 动态数据源。
首先查阅一下 ZookeeperConfigSender,该类主要的做用是将配置写入到 zookeeper 中,其关键代码截图以下:
这个类的测试目的很简单,先将限流规则持久化到 Zookeeper 中,充当的角色与 sentinel-dashboard 的角色一致,故这个类为咱们改造后台管理系统带来很大的启发,便可以经过 zookeeper 存储 sentinel 限流规则,从 demo 示例能够看出限流规则在 zookeeper 中的目录结构,路径为 /{groupId} / {dataid} ,该节点的 value 值存储 json 字符串,存储全部的限流规则。
实践指导,一般基于 zookeeper 的开发,主要是规划好目录结构,关于 Sentinel,我对给出一个初步的目录规划。
在 zookeeper 中建立一个根节点,例如 /sentienl 用来表示限流相关的根目录。
实现存储规则的配置存储后接下来是须要客户端能动态感知规则的变化,从而是配置规则实时生效。
咱们依然先来看一下官方示例,其核心代码如图所示:
这里尽管引入 groupId 与 dataId 的概念是方便与 nacos 进行切换,但就算不切换,基于 zookeeper 的编程,这种目录规划是很是有必要的。上面的示例代码有两个关键点:
客户端在启动的时候会调用 FlowRuleManager 相关方法加载限流相关的配置,那若是配置规则发生变化后,客户端如何动态感知呢?其关键就在于 ZookeeperDataSource 的实现中,其实现关键点以下:
即在构建 ZookeeperDataSource 时会监听 /groupId/dataId 节点,即存放限流配置的节点,一旦数据发生变化,就会通知到客户端,从而调用 loadConfig 从新更新Sentienl 客户端的限流配置,从而实现配置实时生效。
从官方的示例中咱们不难发现,引入 Zookeeper 数据源主要有两个步骤:将数据存储在Zookeeper中以及在客户端监听ZK从而实时生效两个步骤。
sentinel 官方提供了默认的后台管理系统实现:sentinel-dashboard,但其缺点很是明显:基于内存存储,没法用于实际生产过程。你们可能会向后台管理系统将配置信息存储在内存中,那接入的客户端如何从 sentinel-dashboard 的内存中获取配置信息呢,这是由于 sentinel-dashboard 里提供了简单的机器发现,而且内置了 sentinel 客户端之间、sentinel 客户端与 sentinel-dashboard 之间的通信协议,具体由 sentinel-transport 模块实现,目前提供了基于 http 与 netty 的实现方式,故能将 sentinel-dashboard 内存中的配置信息推送到客户端,从而使客户端根据配置进行限流与熔断。
接下来回答本文的重点部分,基于 sentinel-dashboard 如何引入 zookeeper 等动态数据源呢?
首先咱们能够顺着 sentinel-dashboard 的提供的控制器,寻找其后台入口,改造目标也很明确,就是将数据持久化到 zookeeper中,例如增长流控规则的后台处理入口为:
只须要从这里开始改造,将其配置持久化到数据库中和 zookeeper中便可。将数据存储在 zookeeper 中,其关键是设计好各个项目如何有组织有条理的在 zookeeper 中进行组织。我给出以下设计方案:
这样相关管理人员能够直接在 sentinel-dashboard 中配置限流规则,即按照应用为维度进行存储,每个应用再按照维度,例如限流、熔断、热点、集群等维度进行配置,每一分类节点的值存储的是全部的配置,使用 [{},{}] 这种JSON格式进行存储。
目前大部分项目都是基于 SpringBoot,故本文给出基于 SpringBoot 进行的客户端加载实现思路。
利用 SpringBoot 的事件机制,在 Spring 容器初始化后,开始加载 zookeeper 中的配置,其实现思路是读取 zookeeper 中的 /sentinel 下全部的子节点,而后并依次遍历其子节点(appid),而后依次读取 flow(限流)、degrade(熔断)等配置,并调用 Sentinel 的 相关API完成加载,其伪代码以下:
其主要关键点以下:
欢迎加入个人知识星球,一块儿交流源码,探讨架构,揭秘亿级订单的架构设计与实践经验,打造高质量的技术交流圈,为广大星友提供高质量问答服务,长按以下二维码加入。