Apollo 監聽器ConfigListener

Apollo 本身是可以基於事件監聽實時推送(Http長連接)變更(AutoUpdateConfigChangeListener),也會定時拉取(fallback)最新配置。

如果說我們還需要在配置更新時,做一些其他的業務,比如:對配置做了一些自己的數據緩存,或者業務變更等,那麼我們需要控制監聽器,apollo提供了這樣的策略。可手動配置一個監聽器在容器中。

有兩種方式如下:

一、手動初始化監聽器並配置到Config上下文中

@SpringBootApplication
@EnableApolloConfig
public class ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);

        // 手動配置 apolloConfigListener,添加配置改動監聽
        ConfigChangeListener configChangeListener = new ConfigChangeListener() {
            @Override
            public void onChange(ConfigChangeEvent configChangeEvent) {
                ConfigChange change;
                for (String key : configChangeEvent.changedKeys()) {
                    change = configChangeEvent.getChange(key);
                    // 打印改動的配置信息
                    System.out.println(
                            String.format(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
                            change.getPropertyName(), change.getOldValue(), change.getNewValue(),
                            change.getChangeType())));
                }
            }
        };
        // 也可@ApolloConfig注入
        ConfigService.getAppConfig().addChangeListener(configChangeListener);
    }

}

這裏我將實現過程寫在啓動類中,手動實現一個匿名類ConfigListener然後配置到Config中,ConfigService.getAppConfig()是Apollo提供的靜態方法,用於獲取當前容器默認的ApolloConfig,默認是指的namespace是默認“application”,也就是說獲取的是“application”的config,上面這樣操作,監聽的是application。

可以看到getAppConfig的實現:

如果想要獲得其他namespace的話,getConfig(“namespace”),形參爲你所指定的namespace,然後addChangeListener(),即可以監聽指定namespace下的配置變換。可以理解Config是namespace維度下的,每個namespace(同一應用,同一集羣,同一環境)下都一個Config。

支持監聽namespace下指定配置key,提供三個重載方法,默認無參的,則監聽namespace下所有key,下圖中第一個方法監聽指定key,第二個監聽指定以其開頭的key。

使用如下:

        config.addChangeListener(configChangeListener, new HashSet<String>(){{
            add("nwpu.name");
        }}, new HashSet<String>(){{
            add("nwpu");
        }});

二、用@ApolloConfigChangeListener註解標記,自動註冊ConfigChangeListener

@Configuration
public class ApolloConfig {

    @Autowired
    private RefreshScope refreshScope;

    @ApolloConfigChangeListener(value = {"application", "datasource"})
    private void onChangeToAll(ConfigChangeEvent changeEvent) {
        ConfigChange change;
        for (String key : changeEvent.changedKeys()) {
            // 如果@ConfigurationProperties配置發生變化,則需要手動刷新
//            if (key.substring(0, 5).equals("nwpu")) {
//              refreshScope.refresh("nwpuDTO");
//            }
            change = changeEvent.getChange(key);
            // 打印出新增或者變化的配置 相關信息
            System.out.println(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
                    change.getPropertyName(), change.getOldValue(), change.getNewValue(),
                    change.getChangeType()));
        }
    }

    @ApolloConfigChangeListener(value = "application", interestedKeyPrefixes = "nwpu")
    private void onChangeToApplication(ConfigChangeEvent changeEvent) {
        ConfigChange change;
        for (String key : changeEvent.changedKeys()) {
            // 如果@ConfigurationProperties配置發生變化,則需要手動刷新
            refreshScope.refresh("nwpuDTO");
            change = changeEvent.getChange(key);
            // 打印出新增或者變化的配置 相關信息
            System.out.println(String.format("Change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
                    change.getPropertyName(), change.getOldValue(), change.getNewValue(),
                    change.getChangeType()));
        }
    }

}

這種方式應該是用註解標記,然後aop切面標記的方法,然後注入Config中。標記方法的實現是配置變化後的處理業務。

分析上面的代碼,我們總共對兩個config操作,一個application config,一個datasource config,然後分別註冊監聽器,注意application註冊兩次監聽器,第一次沒有指定key,第二次指定了key前綴,測試發現均可用,也就是說config允許同時註冊多個監聽器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章