1 pull模式
1.1 架构设计
该模式的数据源(如本地文件、RDBMS 等)一般可写入。使用时需在客户端注册数据源:将对应读数据源注册至对应的 RuleManager
,将写数据源注册至 transport
的 WritableDataSourceRegistry
中。
如本地文件数据源:
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.register2Property(ds.getProperty());
WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(flowRulePath, this::encodeJson);
// 注册可写数据源至transport模块的这类
// 这样收到控制台推送的规则时,Sentinel先更新到内存,再将规则写入文件
WritableDataSourceRegistry.registerFlowDataSource(wds);
}
private <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
}
本地文件数据源会定时轮询文件的变更,读取规则。这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。如本地文件数据源的推送过程:
1.2 执行流程
FileRefreshableDataSource
定时从指定文件读取规则JSON文件【上图:本地文件】,如果发现文件发生变化,就更新规则缓存FileWritableDataSource
接收控制台规则推送,并根据配置,修改规则JSON文件【图中的本地文件】
1.3 代码实战
1.3.1 添加依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
</dependency>
1.3.2 代码
/**
* 拉模式规则持久化
*/
public class FileDataSourceInit implements InitFunc {
@Override
public void init() throws Exception {
// TIPS: 如果你对这个路径不喜欢,可修改为你喜欢的路径
String ruleDir = System.getProperty("user.home") + "/sentinel/rules";
String flowRulePath = ruleDir + "/flow-rule.json";
String degradeRulePath = ruleDir + "/degrade-rule.json";
String systemRulePath = ruleDir + "/system-rule.json";
String authorityRulePath = ruleDir + "/authority-rule.json";
String paramFlowRulePath = ruleDir + "/param-flow-rule.json";
this.mkdirIfNotExits(ruleDir);
this.createFileIfNotExits(flowRulePath);
this.createFileIfNotExits(degradeRulePath);
this.createFileIfNotExits(systemRulePath);
this.createFileIfNotExits(authorityRulePath);
this.createFileIfNotExits(paramFlowRulePath);
}
}
1.3.3 配置
在项目的 resources/META-INF/services
目录下创建文件:
1.4 优点
简单,不会引入新的依赖。
1.5 缺点
无法保证监控数据的一致性:
- 由于规则是用
FileRefreshableDataSource
定时更新,所以规则更新会有延迟。如果FileRefreshableDataSource
定时时间过大,可能长时间延迟;如果FileRefreshableDataSource
过小,又会影响性能 - 规则存储在本地文件,若某天需迁移微服务,需将规则文件一起迁移,否则规则丢失
2 Push模式
2.1 架构设计
生产环境下更常用 push 模式数据源
如远程配置中心(ZooKeeper, Nacos),推送操作不应由 Sentinel 客户端进行,而应该经控制台统一管理,直接推送。
数据源仅负责获取配置中心推送的配置并更新到本地
因此推送规则正确做法:
配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel
而非经 Sentinel 数据源推至配置中心。
可得设计:
官方提供zk、Apollo和Nacos等动态数据源实现:
若用第三方配置中心如 zk作配置管理,还需:
- 实现一个公共的zk客户端用于推送规则,在 Sentinel 控制台配置项中需要指定 zk 的地址,启动时即创建 ZooKeeper Client
- 针对每个应用(appName),每种规则设置不同的 path(可随时修改);或者约定大于配置(如 path 的模式统一为
/sentinel_rules/{appName}/{ruleType}
,e.g.sentinel_rules/appA/flowRule
) - 规则配置页需要进行相应的改造,直接针对应用维度进行规则配置;修改同个应用多个资源的规则时可以批量进行推送,也可以分别推送。Sentinel 控制台将规则缓存在内存中(如 InMemFlowRuleStore),可以对其进行改造使其支持应用维度的规则缓存(key 为 appName),每次添加/修改/删除规则都先更新内存中的规则缓存,然后需要推送的时候从规则缓存中获取全量规则,再通过上面实现的 Client 将规则推送到zk
- 应用客户端需注册对应的读数据源以监听变更。Sentinel 1.4.0 开始,Sentinel 控制台提供 DynamicRulePublisher、DynamicRuleProvider 接口用于实现应用维度的规则推送和拉取,并提供了相关的示例。Sentinel提供应用维度规则推送的示例页面(/v2/flow),用户改造控制台对接配置中心后可直接通过 v2 页面推送规则至配置中心
部署多个控制台实例时,通常需要将规则存至 DB 中,规则变更后同步向配置中心推送规则。
2.2 执行流程
控制台推送规则
- 将规则推送到Nacos或其他远程配置中心
- Sentinel客户端链接Nacos,获取规则配置;并监听Nacos配置变化,如发生变化,就更新本地缓存(从而让本地缓存总是和Nacos一致)
控制台监听Nacos配置变化,如发生变化就更新本地缓存(从而让控制台本地缓存总是和Nacos一致)
2.3 实战
2.3.1 添加依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2.3.2 修改配置
spring:
cloud:
sentinel:
datasource:
# 名称随意
flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
groupId: SENTINEL_GROUP
# 规则类型,取值见:
# org.springframework.cloud.alibaba.sentinel.datasource.RuleType
rule-type: flow
degrade:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-degrade-rules
groupId: SENTINEL_GROUP
rule-type: degrade
system:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-system-rules
groupId: SENTINEL_GROUP
rule-type: system
authority:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-authority-rules
groupId: SENTINEL_GROUP
rule-type: authority
param-flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-param-flow-rules
groupId: SENTINEL_GROUP
rule-type: param-flow
重启服务。
3 最佳实践
推拉模式持久化规则
- 推模式更佳
AHAS
- 开通地址:https://ahas.console.aliyun.com/
- 开通说明:https://help.aliyun.com/document detail/90323.html
参考: