apollo持久化sentinel_Sentinel Client: 整合Apollo规则持久化

本文介绍了如何使用Apollo配置中心实现Sentinel规则的持久化,包括集成依赖、创建ApolloDataSource并注册到RuleManager,以及详细解析配置和加载规则的过程。通过Apollo动态更新Sentinel规则,确保应用程序重启后规则不会丢失。
摘要由CSDN通过智能技术生成

在前面的学习过程中,Sentinel 的规则,也就是我们之前定义的限流规则,是通过代码的方式定义好的。这是初始化时需要做的事情,Sentinel 提供了基于API的方式修改规则:

FlowRuleManager.loadRules(List rules); // 修改流控规则

DegradeRuleManager.loadRules(List rules); // 修改降级规则

SystemRuleManager.loadRules(List rules); // 修改系统规则

AuthorityRuleManager.loadRules(List rules); // 修改授权规则

当我们接入了控制台后,可以通过控制台进行规则的动态修改,问题是当应用程序重启后规则信息就会恢复到初始化的阶段,也就是说后面修改的值会丢失,因为规则信息都是存储在应用的内存中。

为了解决这个问题Sentinel 提供了DataSource 扩展的功能,官方推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更,流程如下:

扩展的常见方式有推和拉两种模式:

拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;

推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Apollo、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

今天我们主要是讲如何使用 Apollo 来配置规则进行持久化,Apollo是携程开源的配置中心,非常好用

在我的书中也有对Apollo使用的详细介绍,等出版了再通知大家。

首先集成需要的依赖:

com.alibaba.csp

sentinel-datasource-apollo

1.4.1

然后创建 ApolloDataSource 并将其注册至对应的 RuleManager 上即可。比如:

private static void loadRules() {

// Apollo 中的应用名称,自己定义的

String appId = "SampleApp";

// Apollo 的地址

String apolloMetaServerAddress = "http://localhost:8080";

System.setProperty("app.id", appId);

System.setProperty("apollo.meta", apolloMetaServerAddress);

// 指定环境

System.setProperty("env", "DEV");

// Apollo 的命名空间

String namespaceName = "application";

// 限流规则的Key, 在Apollo中用此Key

String flowRuleKey = "flowRules";

// 限流规则的默认值

String defaultFlowRules = "[]";

// 注册数据源

ReadableDataSource> flowRuleDataSource = new ApolloDataSource<>(namespaceName,

flowRuleKey, defaultFlowRules, source -> JSON.parseObject(source, new TypeReference>() {

}));

FlowRuleManager.register2Property(flowRuleDataSource.getProperty());

}

到此为止配置就结束了,详细的解释我都写了注释哈。官方文档也是这么写的,问题是如果你刚接触会一头雾水的,为什么?

你不知道在Apollo中怎么配置啊,我们讲的就是说可以用Apollo来作为存储,持久化规则,那么规则怎么配置就需要我们自己去想。

我也是通过看源码才知道怎么去配置的,带着大家一起来看源码吧!

主要就是new ApolloDataSource这里,参数都是通过这里传进去的

public ApolloDataSource(String namespaceName, String flowRulesKey, String defaultFlowRuleValue,

Converter parser) {

super(parser);

Preconditions.checkArgument(!Strings.isNullOrEmpty(namespaceName), "Namespace name could not be null or empty");

Preconditions.checkArgument(!Strings.isNullOrEmpty(flowRulesKey), "FlowRuleKey could not be null or empty!");

this.flowRulesKey = flowRulesKey;

this.defaultFlowRuleValue = defaultFlowRuleValue;

this.config = ConfigService.getConfig(namespaceName);

initialize();

RecordLog.info(String.format("Initialized rule for namespace: %s, flow rules key: %s",

namespaceName, flowRulesKey));

}

这边就是对传入的参数赋值,然后看下面这行:

this.config = ConfigService.getConfig(namespaceName);

这就是通过命名空间去Apollo中获取配置,获取完后就执行初始化

private void initialize() {

initializeConfigChangeListener();

loadAndUpdateRules();

}

initializeConfigChangeListener是初始化配置的监听器,当配置发生修改时会进入该监听器,也就是说在这个监听器里需要监听配置的修改,然后更新规则

private void initializeConfigChangeListener() {

config.addChangeListener(new ConfigChangeListener() {

@Override

public void onChange(ConfigChangeEvent changeEvent) {

ConfigChange change = changeEvent.getChange(flowRulesKey);

//change is never null because the listener will only notify for this key

if (change != null) {

RecordLog.info("[ApolloDataSource] Received config changes: " + change.toString());

}

loadAndUpdateRules();

}

}, Sets.newHashSet(flowRulesKey));

}

loadAndUpdateRules就是更新规则的逻辑了

private void loadAndUpdateRules() {

try {

T newValue = loadConfig();

if (newValue == null) {

RecordLog.warn("[ApolloDataSource] WARN: rule config is null, you may have to check your data source");

}

getProperty().updateValue(newValue);

} catch (Throwable ex) {

RecordLog.warn("[ApolloDataSource] Error when loading rule config", ex);

}

}

那么配置是怎么来的呢,请看loadConfig

@Override

public T loadConfig() throws Exception {

return loadConfig(readSource());

}

public T loadConfig(S conf) throws Exception {

T value = parser.convert(conf);

return value;

}

readSource就是获取我们配置的flowRulesKey的值,那么配置其实就是一个字符串,然后下面通过Json转换

public String readSource() throws Exception {

return config.getProperty(flowRulesKey, defaultFlowRuleValue);

}

我们再返过来看看注册的代码:

// 注册数据源

ReadableDataSource> flowRuleDataSource = new ApolloDataSource<>(namespaceName,

flowRuleKey, defaultFlowRules, source -> JSON.parseObject(source, new TypeReference>() {

}));

重点是ource -> JSON.parseObject(source, new TypeReference()这行,这不就是转换成List吗,真相呼之欲出了,也就是在Apollo中配置的就是List的json格式就行。

我们配置一个试试看:

flowRules = [{"grade":1,"count":11,"resource":"HelloWorld"}]

点击保存并且发布,可以在initializeConfigChangeListener里面设置一个断点,你会发现,当发布配置之后,这边马上就会进来,然后执行其他的逻辑,到此为止整个流程结束。

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)

PS:目前星球中正在星主的带领下组队学习Sentinel,等你哦!

root@in_dev_docker:/apollo# bash scripts/msf_create_lossless_map.sh /apollo/hdmap/pcd_apollo/ 50 /apollo/hdmap/ /apollo/bazel-bin WARNING: Logging before InitGoogleLogging() is written to STDERR E0715 22:08:35.399576 6436 lossless_map_creator.cc:162] num_trials = 1 Pcd folders are as follows: /apollo/hdmap/pcd_apollo/ Resolution: 0.125 Dataset: /apollo/hdmap/pcd_apollo Dataset: /apollo/hdmap/pcd_apollo/ Loaded the map configuration from: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. E0715 22:08:35.767315 6436 lossless_map_creator.cc:264] ieout_poses = 1706 Failed to find match for field 'intensity'. Failed to find match for field 'timestamp'. E0715 22:08:35.769896 6436 velodyne_utility.cc:46] Un-organized-point-cloud E0715 22:08:35.781770 6436 lossless_map_creator.cc:275] Loaded 245443D Points at Trial: 0 Frame: 0. F0715 22:08:35.781791 6436 base_map_node_index.cc:101] Check failed: false *** Check failure stack trace: *** scripts/msf_create_lossless_map.sh: line 11: 6436 Aborted (core dumped) $APOLLO_BIN_PREFIX/modules/localization/msf/local_tool/map_creation/lossless_map_creator --use_plane_inliers_only true --pcd_folders $1 --pose_files $2 --map_folder $IN_FOLDER --zone_id $ZONE_ID --coordinate_type UTM --map_resolution_type single root@in_dev_docker:/apollo# bash scripts/msf_create_lossless_map.sh /apollo/hdmap/pcd_apollo/ 50 /apollo/hdmap/
07-16
根据提供的信息,执行脚本 `scripts/msf_create_lossless_map.sh` 时出现了错误。具体的错误信息如: ``` E0715 22:08:35.399576 6436 lossless_map_creator.cc:162] num_trials = 1 Pcd folders are as follows: /apollo/hdmap/pcd_apollo/ Resolution: 0.125 Dataset: /apollo/hdmap/pcd_apollo Dataset: /apollo/hdmap/pcd_apollo/ Loaded the map configuration from: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. Saved the map configuration to: /apollo/hdmap//lossless_map/config.xml. E0715 22:08:35.767315 6436 lossless_map_creator.cc:264] ieout_poses = 1706 Failed to find match for field 'intensity'. Failed to find match for field 'timestamp'. E0715 22:08:35.769896 6436 velodyne_utility.cc:46] Un-organized-point-cloud E0715 22:08:35.781770 6436 lossless_map_creator.cc:275] Loaded 245443D Points at Trial: 0 Frame: 0. F0715 22:08:35.781791 6436 base_map_node_index.cc:101] Check failed: false *** Check failure stack trace: *** scripts/msf_create_lossless_map.sh: line 11: 6436 Aborted (core dumped) $APOLLO_BIN_PREFIX/modules/localization/msf/local_tool/map_creation/lossless_map_creator --use_plane_inliers_only true --pcd_folders $1 --pose_files $2 --map_folder $IN_FOLDER --zone_id $ZONE_ID --coordinate_type UTM --map_resolution_type single ``` 这段错误信息表明在执行脚本时发生了一个检查失败的情况。错误的具体位置在 `base_map_node_index.cc:101`。可能的原因包括: 1. 数据不匹配:脚本中使用的数据可能存在不匹配的情况,例如字段名或者数据格式不正确。 2. 数据文件缺失:脚本所需的某些数据文件可能不存在或者路径不正确。 3. 依赖问题:脚本所依赖的某些组件或库可能缺失或者版本不兼容。 请检查脚本 `scripts/msf_create_lossless_map.sh` 中的相关代码,确保数据文件和依赖项的正确性。如果问题仍然存在,您可以提供更多的上下文信息,以便我们能够更好地帮助您解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值