Soul Admin
负责将配置元数据信息发布到Nacos配置中心。
核心类
NacosDataChangedListener
NacosDataChangedListener实现了DataChangedListener接口
DataChangedListener接口功能是一旦插件、选择器、规则、元数据信息有变更就会被调用
NacosDataChangedListener.java
// 从Nacos获取数据
private String getConfig(final String dataId) {
String config = configService.getConfig(dataId, GROUP, 6000);
return StringUtils.hasLength(config) ? config : EMPTY_CONFIG_DEFAULT_VALUE;
}
// 将数据发布到Nacos配置中心中
private void publishConfig(final String dataId, final Object data) {
configService.publishConfig(dataId, GROUP, GsonUtils.getInstance().toJson(data));
}
// 当插件配置数据有变更,会触发此方法
public void onPluginChanged(final List<PluginData> changed, final DataEventTypeEnum eventType) {
// 先同步更新到自已本地内存中
updatePluginMap(getConfig(PLUGIN_DATA_ID));
// 根据事件类型,做不同的操作
switch (eventType) {
case DELETE:
// 删除插件配置
changed.forEach(plugin -> PLUGIN_MAP.remove(plugin.getName()));
break;
case REFRESH: // 刷新
case MYSELF: // 全量同步
Set<String> set = new HashSet<>(PLUGIN_MAP.keySet());
changed.forEach(plugin -> {
set.remove(plugin.getName());
PLUGIN_MAP.put(plugin.getName(), plugin);
});
PLUGIN_MAP.keySet().removeAll(set);
break;
default: // 默认
changed.forEach(plugin -> PLUGIN_MAP.put(plugin.getName(), plugin));
break;
}
// 将最新的数据全量发布到Nacos配置中心中
publishConfig(PLUGIN_DATA_ID, PLUGIN_MAP);
}
// 元数据变更时更新本地内存同时发布到Nacos上(和插件变更逻辑一样)
public void onMetaDataChanged(final List<MetaData> changed, final DataEventTypeEnum eventType) {...}
// 规则数据变更时更新本地内存同时发布到Nacos上(和插件变更逻辑一样)
public void onRuleChanged(final List<RuleData> changed, final DataEventTypeEnum eventType) {...}
// 选择器数据变更时更新本地内存同时发布到Nacos上(和插件变更逻辑一样)
public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {...}
Soul网关
将Listener注册到Nacos中,一旦Listener所关心的配置数据有变更,那么Nacos就会把变更后的数据push到Soul网关本地内存中。
核心类
NacosCacheHandler
当Soul网关启时,会向Nacos注册Listener
// 网关启动时,被调用
public void start() {
// 向Nacos注册Listener,并设置回调方法 updatePluginMap方法
watcherData(PLUGIN_DATA_ID, this::updatePluginMap);
}
// 向Nacos注册Listener
// OcChange是回调接口负责将变更的数据写入到本地内存中
protected void watcherData(final String dataId, final OnChange oc) {
// 创建Listener
Listener listener = new Listener() {
// 配置数据有变更,Nacos Client会调用此方法
@Override
public void receiveConfigInfo(final String configInfo) {
oc.change(configInfo);
}
@Override
public Executor getExecutor() {
return null;
}
};
// 获取配置数据并注册Listener
oc.change(getConfigAndSignListener(dataId, listener));
// 将Listener 放入到Map中
LISTENERS.getOrDefault(dataId, new ArrayList<>()).add(listener);
}
// 获取配置数据并注册Listener,用来监听数据变更
private String getConfigAndSignListener(final String dataId, final Listener listener) {
return configService.getConfigAndSignListener(dataId, GROUP, 6000, listener);
}
// 最新的数据更新本地内存中。
protected void updatePluginMap(final String configInfo) {
//...
}
总结
- 了解Soul网关是如何通过Nacos进行数据同步。
遇到问题
采用nacos进行数据同步时,当Soul Admin启动时,不会向Nacos发布全量的配置信息。当Soul Admin更新配置信息,会向Nacas分布最新的配置信息。不知道是我哪个地方少配置了或是配置有问题。后继有时间再进行排查。我先学学Nacos,然后再解决此问题。