[TOC] ## 一、引言 Sentinel 核心库目前已可用于生产环境,目前除了阿里巴巴以外,也有多家企业在生产环境中使用它们。 生产环境的 Sentinel Dashboard 需要具备下面几个特性: * **[规则管理及推送](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#%E8%A7%84%E5%88%99%E7%AE%A1%E7%90%86%E5%8F%8A%E6%8E%A8%E9%80%81)**,集中管理和推送规则。`sentinel-core`提供 API 和扩展接口来接收信息。开发者需要根据自己的环境,选取一个可靠的推送规则方式;同时,规则最好在控制台中集中管理。 * **[监控](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#%E7%9B%91%E6%8E%A7)**,支持可靠、快速的实时监控和历史监控数据查询。`sentinel-core`记录秒级的资源运行情况,并且提供 API 来拉取资源运行信息。当机器大于一台以上的时候,可以通过 Dashboard 来拉取,聚合,并且存储这些信息。这个时候,Dashboard 需要有一个存储媒介,来存储历史运行情况。 * **权限控制**,区分用户角色,来进行操作。生产环境下的权限控制是非常重要的,理论上只有管理员等高级用户才有权限去修改应用的规则。 由于开发者有各自不一样的环境和需求,我们会对“规则管理和推送”,“监控”这两个方面给出建议以及[最佳实践](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5);对于权限控制,由于每个开发者的环境都不一样,我们在最佳实践中仅仅使用了简单的认证。开发者可以依循自己的需求,结合实际生产环境,选择最适合自己的方式。 同时我们也在云上提供[企业级的 Sentinel 控制台](https://github.com/alibaba/Sentinel/wiki/AHAS-Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0),欢迎大家体验。 ## 二、规则管理及推送 一般来说,规则的推送有下面三种模式: | 推送模式 | 说明 | 优点 | 缺点 | | :-: | :-- | :-- | :-- | | [原始模式](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#%E5%8E%9F%E5%A7%8B%E6%A8%A1%E5%BC%8F) | API 将规则推送至客户端并直接更新到内存中,扩展写数据源([`WritableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)) | 简单,无任何依赖 | 不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境 | | [Pull 模式](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#Pull%E6%A8%A1%E5%BC%8F) | 扩展写数据源([`WritableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等 | 简单,无任何依赖;规则持久化 | 不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。 | | **[Push 模式](https://github.com/alibaba/Sentinel/wiki/%E5%9C%A8%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Sentinel#Push%E6%A8%A1%E5%BC%8F)** | 扩展读数据源([`ReadableDataSource`](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。**生产环境下一般采用 push 模式的数据源。** | 规则持久化;一致性;快速 | 引入第三方依赖 | ### 1\. 原始模式 如果不做任何修改,Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中 这种做法的好处是简单,无依赖;坏处是应用重启规则就会消失,仅用于简单测试,不能用于生产环境。 ### 2\. Pull模式 pull 模式的数据源(如本地文件、RDBMS 等)一般是可写入的。使用时需要在客户端注册数据源:将对应的读数据源注册至对应的 RuleManager,将写数据源注册至 transport 的`WritableDataSourceRegistry`中。以本地文件数据源为例: ~~~java public class FileDataSourceInit implements InitFunc { @Override public void init() throws Exception { String flowRulePath = "xxx"; ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>( flowRulePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}) ); // 将可读数据源注册至 FlowRuleManager. FlowRuleManager.register2Property(ds.getProperty()); WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson); // 将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中. // 这样收到控制台推送的规则时,Sentinel 会先更新到内存,然后将规则写入到文件中. WritableDataSourceRegistry.registerFlowDataSource(wds); } private <T> String encodeJson(T t) { return JSON.toJSONString(t); } } ~~~ 本地文件数据源会定时轮询文件的变更,读取规则。这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。以本地文件数据源为例,推送过程如下图所示: ![Push rules from Sentinel Dashboard to local file](https://camo.githubusercontent.com/991ac2f6a21b0a54263576341d3beca9edc93389/68747470733a2f2f63646e2e6e6c61726b2e636f6d2f6c61726b2f302f323031382f706e672f34373638382f313533363636303331313832362d61646466346666362d396663392d343538362d626138622d3463616633613931343537642e706e67) 首先 Sentinel 控制台通过 API 将规则推送至客户端并更新到内存中,接着注册的写数据源会将新的规则保存到本地的文件中。使用 pull 模式的数据源时一般不需要对 Sentinel 控制台进行改造。 这种实现方法好处是简单,不引入新的依赖,坏处是无法保证监控数据的一致性。 ### 3\. Push模式 生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是**配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel**,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了: ![](https://img.kancloud.cn/e6/d0/e6d0a97432dbbce1a612ee82eb99acd5_1506x876.png) 我们提供了 ZooKeeper, Apollo, Nacos 等的动态数据源实现。以 ZooKeeper 为例子,如果要使用第三方的配置中心作为配置管理,您需要做下面的几件事情: 1. 实现一个公共的 ZooKeeper 客户端用于推送规则,在 Sentinel 控制台配置项中需要指定 ZooKeeper 的地址,启动时即创建 ZooKeeper Client。 2. 我们需要针对每个应用(appName),每种规则设置不同的 path(可随时修改);或者约定大于配置(如 path 的模式统一为`/sentinel_rules/{appName}/{ruleType}`,e.g.`sentinel_rules/appA/flowRule`)。 3. 规则配置页需要进行相应的改造,直接针对**应用维度**进行规则配置;修改同个应用多个资源的规则时可以批量进行推送,也可以分别推送。Sentinel 控制台将规则缓存在内存中(如`InMemFlowRuleStore`),可以对其进行改造使其支持应用维度的规则缓存(key 为 appName),每次添加/修改/删除规则都先更新内存中的规则缓存,然后需要推送的时候从规则缓存中获取全量规则,然后通过上面实现的 Client 将规则推送到 ZooKeeper 即可。 4. 应用客户端需要注册对应的读数据源以监听变更,可以参考[相关文档](https://github.com/alibaba/Sentinel/wiki/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%99%E6%89%A9%E5%B1%95)。 从 Sentinel 1.4.0 开始,Sentinel 控制台提供`DynamicRulePublisher`和`DynamicRuleProvider`接口用于实现应用维度的规则推送和拉取,并提供了相关的示例。Sentinel 提供应用维度规则推送的示例页面(`/v2/flow`),用户改造控制台对接配置中心后可直接通过 v2 页面推送规则至配置中心。改造详情可参考[应用维度规则推送示例](https://github.com/alibaba/Sentinel/wiki/Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0%EF%BC%88%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7%E7%AE%A1%E7%90%86%EF%BC%89#%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE)。 部署多个控制台实例时,通常需要将规则存至 DB 中,规则变更后同步向配置中心推送规则。 ## 三、监控 Sentinel 会记录资源访问的秒级数据(若没有访问则不进行记录)并保存在本地日志中,具体格式请见[秒级监控日志文档](https://github.com/alibaba/Sentinel/wiki/%E6%97%A5%E5%BF%97#%E7%A7%92%E7%BA%A7%E7%9B%91%E6%8E%A7%E6%97%A5%E5%BF%97)。Sentinel 控制台可以通过[Sentinel 客户端预留的 HTTP API](https://github.com/alibaba/Sentinel/wiki/%E5%AE%9E%E6%97%B6%E7%9B%91%E6%8E%A7#%E5%AE%9E%E6%97%B6%E6%9F%A5%E8%AF%A2)从秒级监控日志中拉取监控数据,并进行聚合。 目前 Sentinel 控制台中监控数据聚合后直接存在内存中,未进行持久化,且仅保留最近 5 分钟的监控数据。若需要监控数据持久化的功能,可以自行扩展实现`MetricsRepository`接口(0.2.0 版本),然后注册成 Spring Bean 并在相应位置通过`@Qualifier`注解指定对应的 bean name 即可。`MetricsRepository`接口定义了以下功能: * `save`与`saveAll`:存储对应的监控数据 * `queryByAppAndResourceBetween`:查询某段时间内的某个应用的某个资源的监控数据 * `listResourcesOfApp`:查询某个应用下的所有资源 其中默认的监控数据类型为`MetricEntity`,包含应用名称、时间戳、资源名称、异常数、请求通过数、请求拒绝数、平均响应时间等信息。对于监控数据的存储,用户需要根据自己的存储精度,来考虑如何存储这些监控数据。部署多个控制台实例时,通常需要仔细设计下监控拉取和写入策略。 同时用户可以自行进行扩展,适配 Grafana 等可视化平台,以便将监控数据更好地进行可视化。 ## 四、最佳实践 我们提供了一个云上版本的控制台。通过这个版本,开发者可以看到一个完整的生产环境的控制台的功能全集。它主要包括: * 可靠的实时监控和历史监控数据查询:该控制台将会示范 Sentinel 的监控能做成什么样子,包括实时监控、集群热力图等,请参考“监控”以及“簇点链路”模块。 * 动态规则管理/推送:该控制台将会示范如何做一个合理的 push 结构的实现,请参考“规则”模块。 * 机器列表:如何利用 Sentinel 上报的机器信息进行管理,请参考“机器列表”模块。 详情请参考[AHAS Sentinel 控制台文档](https://github.com/alibaba/Sentinel/wiki/AHAS-Sentinel-%E6%8E%A7%E5%88%B6%E5%8F%B0)来参考如何在生产环境中使用控制台。 ## 五、其它 [Awesome Sentinel](https://github.com/alibaba/sentinel-awesome)里记录非常多的社区用户的一些扩展和解决方案,也欢迎大家将一些比较好的扩展实现添加进来。