概述
当资源定义成功后可以动态增加各种流控降级规则,Sentinel提供两种方式修改规则:
- 通过 API 直接修改(
loadRules
) - 通过
DataSource
适配不同数据源修改
DataSource 扩展
我们推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更
DataSource 扩展常见的实现方式
- 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更
- 推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证
Sentinel 目前支持以下数据源扩展:
- Pull-based: 文件、Consul
- Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd
拉模式拓展
实现拉模式的数据源最简单的方式是继承 AutoRefreshDataSource
抽象类,然后实现 readSource()
方法,在该方法里从指定数据源读取字符串格式的配置数据,可参考案例
推模式拓展
实现推模式的数据源最简单的方式是继承 AbstractDataSource
抽象类,在其构造方法中添加监听器,并实现 readSource()
从指定数据源读取字符串格式的配置数据,可参考案例
案例
拉模式:使用文件配置规则
1、首先添加pom依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<version>x.y.z</version>
</dependency>
2、注册数据源
// 已json文件为限流规则
String resource = URLDecoder.decode(getClass().getClassLoader().getResource("flowRules.json").getFile(), "UTF-8");
// 使用指定文件或对应的转换器创建一个文件数据源
FileRefreshableDataSource<List<FlowRule>> fileRefreshableDataSource = new FileRefreshableDataSource<List<FlowRule>>(resource, fileRefreshableDataSourceConverter());
// 在流控管理器上注册这个数据源使其数据源变得可用,这个FileRefreshableDataSource会周期性的获取文件内容来进行更新规则
FlowRuleManager.register2Property(fileRefreshableDataSource.getProperty());
// fileRefreshableDataSourceConverter()方法实现
private Converter<String, List<FlowRule>> fileRefreshableDataSourceConverter() {
return fileContent -> {
// fileContent是这个文件的内容
List<FlowRule> flowRules = new ArrayList<>();
JSONArray array = JSONObject.parseArray(fileContent);
if (!array.isEmpty()) {
for (int i = 0; i < array.size(); i++) {
JSONObject json = array.getJSONObject(i);
FlowRule flowRule = new FlowRule();
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setCount(json.getInteger("count"));
flowRule.setResource(json.getString("resource"));
flowRules.add(flowRule);
}
}
// 最终返回一个FlowRule的集合
return flowRules;
};
}
推模式-Nacos
1、添加Sentinel的Nacos依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
2. 注册数据源
// 我们使用Nacos中组为'DEFAULT',ID为'dubb-sentinel-config.json'的配置作为数据来源
NacosDataSource<List<FlowRule>> dataSource = new NacosDataSource<>("localhost", "DEFUALT", "dubb-sentinel-config.json", converter());
// 给限流规则管理器注册
FlowRuleManager.register2Property(dataSource.getProperty());
// 配置转换器,使用Nacos指定的的资源来进行转换
private Converter<String, List<FlowRule>> converter (){
return content->{
JSONArray json = JSON.parseArray(content);
ArrayList<FlowRule> flowRules = new ArrayList<>();
if(json != null && !json.isEmpty()){
for (int i = 0; i < json.size(); i++) {
FlowRule flowRule = new FlowRule(json.getJSONObject(i).getString("resourceName"));
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setCount(json.getJSONObject(i).getInteger("count"));
flowRules.add(flowRule);
}
}
return flowRules;
};
}