Soul源碼閱讀7-基于Nacos數(shù)據(jù)同步

Soul Admin

負(fù)責(zé)將配置元數(shù)據(jù)信息發(fā)布到Nacos配置中心。

核心類

NacosDataChangedListener

NacosDataChangedListener實(shí)現(xiàn)了DataChangedListener接口

DataChangedListener接口功能是一旦插件、選擇器、規(guī)則、元數(shù)據(jù)信息有變更就會(huì)被調(diào)用

NacosDataChangedListener.java

// 從Nacos獲取數(shù)據(jù)
private String getConfig(final String dataId) {
    String config = configService.getConfig(dataId, GROUP, 6000);
    return StringUtils.hasLength(config) ? config : EMPTY_CONFIG_DEFAULT_VALUE;
}

// 將數(shù)據(jù)發(fā)布到Nacos配置中心中
private void publishConfig(final String dataId, final Object data) {
    configService.publishConfig(dataId, GROUP, GsonUtils.getInstance().toJson(data));
}

// 當(dāng)插件配置數(shù)據(jù)有變更,會(huì)觸發(fā)此方法
public void onPluginChanged(final List<PluginData> changed, final DataEventTypeEnum eventType) {
    // 先同步更新到自已本地內(nèi)存中
    updatePluginMap(getConfig(PLUGIN_DATA_ID));
    // 根據(jù)事件類型,做不同的操作
    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: // 默認(rèn)
            changed.forEach(plugin -> PLUGIN_MAP.put(plugin.getName(), plugin));
            break;
    }
    // 將最新的數(shù)據(jù)全量發(fā)布到Nacos配置中心中
    publishConfig(PLUGIN_DATA_ID, PLUGIN_MAP);
}

// 元數(shù)據(jù)變更時(shí)更新本地內(nèi)存同時(shí)發(fā)布到Nacos上(和插件變更邏輯一樣)
public void onMetaDataChanged(final List<MetaData> changed, final DataEventTypeEnum eventType) {...}

// 規(guī)則數(shù)據(jù)變更時(shí)更新本地內(nèi)存同時(shí)發(fā)布到Nacos上(和插件變更邏輯一樣)
public void onRuleChanged(final List<RuleData> changed, final DataEventTypeEnum eventType) {...}

// 選擇器數(shù)據(jù)變更時(shí)更新本地內(nèi)存同時(shí)發(fā)布到Nacos上(和插件變更邏輯一樣)
public void onSelectorChanged(final List<SelectorData> changed, final DataEventTypeEnum eventType) {...}

Soul網(wǎng)關(guān)

將Listener注冊(cè)到Nacos中,一旦Listener所關(guān)心的配置數(shù)據(jù)有變更,那么Nacos就會(huì)把變更后的數(shù)據(jù)push到Soul網(wǎng)關(guān)本地內(nèi)存中。

核心類

NacosCacheHandler

當(dāng)Soul網(wǎng)關(guān)啟時(shí),會(huì)向Nacos注冊(cè)Listener

// 網(wǎng)關(guān)啟動(dòng)時(shí),被調(diào)用
public void start() {
    // 向Nacos注冊(cè)Listener,并設(shè)置回調(diào)方法 updatePluginMap方法
    watcherData(PLUGIN_DATA_ID, this::updatePluginMap);
}

// 向Nacos注冊(cè)Listener
// OcChange是回調(diào)接口負(fù)責(zé)將變更的數(shù)據(jù)寫入到本地內(nèi)存中
protected void watcherData(final String dataId, final OnChange oc) {
   // 創(chuàng)建Listener
    Listener listener = new Listener() {
       // 配置數(shù)據(jù)有變更,Nacos Client會(huì)調(diào)用此方法
        @Override
        public void receiveConfigInfo(final String configInfo) {
            oc.change(configInfo);
        }

        @Override
        public Executor getExecutor() {
            return null;
        }
    };
    // 獲取配置數(shù)據(jù)并注冊(cè)Listener
    oc.change(getConfigAndSignListener(dataId, listener));
    // 將Listener 放入到Map中
    LISTENERS.getOrDefault(dataId, new ArrayList<>()).add(listener);
}

// 獲取配置數(shù)據(jù)并注冊(cè)Listener,用來監(jiān)聽數(shù)據(jù)變更
private String getConfigAndSignListener(final String dataId, final Listener listener) {
    return configService.getConfigAndSignListener(dataId, GROUP, 6000, listener);
}

// 最新的數(shù)據(jù)更新本地內(nèi)存中。
protected void updatePluginMap(final String configInfo) {
    //...
}

總結(jié)

  • 了解Soul網(wǎng)關(guān)是如何通過Nacos進(jìn)行數(shù)據(jù)同步。

遇到問題

采用nacos進(jìn)行數(shù)據(jù)同步時(shí),當(dāng)Soul Admin啟動(dòng)時(shí),不會(huì)向Nacos發(fā)布全量的配置信息。當(dāng)Soul Admin更新配置信息,會(huì)向Nacas分布最新的配置信息。不知道是我哪個(gè)地方少配置了或是配置有問題。后繼有時(shí)間再進(jìn)行排查。我先學(xué)學(xué)Nacos,然后再解決此問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容