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,然后再解決此問題。