轉載於https://github.com/ctripcorp/apollo,by Ctrip, Inc.java
Namespace是配置項的集合,相似於一個配置文件的概念。git
Apollo在建立項目的時候,都會默認建立一個「application」的Namespace。顧名思義,「application」是給應用自身使用的,熟悉Spring Boot的同窗都知道,Spring Boot項目都有一個默認配置文件application.yml。在這裏application.yml就等同於「application」的Namespace。對於90%的應用來講,「application」的Namespace已經知足平常配置使用場景了。github
Config config = ConfigService.getAppConfig();
Config config = ConfigService.getConfig(namespaceName);
配置文件有多種格式,例如:properties、xml、yml、yaml、json等。一樣Namespace也具備這些格式。在Portal UI中能夠看到「application」的Namespace上有一個「properties」標籤,代表「application」是properties格式的。json
注:非properties格式的namespace,在客戶端使用時須要調用
ConfigService.getConfigFile(String namespace, ConfigFileFormat configFileFormat)
來獲取,若是使用Http接口直接調用時,對應的namespace參數須要傳入namespace的名字加上後綴名,如datasources.json。markdown
Namespace的獲取權限分爲兩種:app
這裏的獲取權限是相對於Apollo客戶端來講的。框架
private權限的Namespace,只能被所屬的應用獲取到。一個應用嘗試獲取其它應用private的Namespace,Apollo會報「404」異常。flex
public權限的Namespace,能被任何應用獲取。spa
Namespace類型有三種:3d
私有類型的Namespace具備private權限。例如上文提到的「application」 Namespace就是私有類型。
公共類型的Namespace具備public權限。公共類型的Namespace至關於遊離於應用以外的配置,且經過Namespace的名稱去標識公共Namespace,因此公共的Namespace的名稱必須全局惟一。
關聯類型又可稱爲繼承類型,關聯類型具備private權限。關聯類型的Namespace繼承於公共類型的Namespace,用於覆蓋公共Namespace的某些配置。例如公共的Namespace有兩個配置項
k1 = v1 k2 = v2
而後應用A有一個關聯類型的Namespace關聯了此公共Namespace,且覆蓋了配置項k1,新值爲v3。那麼在應用A實際運行時,獲取到的公共Namespace的配置爲:
k1 = v3
k2 = v2
舉一個實際使用的場景。假設RPC框架的配置(如:timeout)有如下要求:
以下圖所示,有三個應用:應用A、應用B、應用C。
//application Config appConfig = ConfigService.getAppConfig(); appConfig.getProperty("k1", null); // k1 = v11 appConfig.getProperty("k2", null); // k2 = v21 //NS-Private Config privateConfig = ConfigService.getConfig("NS-Private"); privateConfig.getProperty("k1", null); // k1 = v3 privateConfig.getProperty("k3", null); // k3 = v4 //NS-Public,覆蓋公共類型配置的狀況,k4被覆蓋 Config publicConfig = ConfigService.getConfig("NS-Public"); publicConfig.getProperty("k4", null); // k4 = v6 cover publicConfig.getProperty("k6", null); // k6 = v6 publicConfig.getProperty("k7", null); // k7 = v7
//application Config appConfig = ConfigService.getAppConfig(); appConfig.getProperty("k1", null); // k1 = v12 appConfig.getProperty("k2", null); // k2 = null appConfig.getProperty("k3", null); // k3 = v32 //NS-Private,因爲沒有NS-Private Namespace 因此獲取到default value Config privateConfig = ConfigService.getConfig("NS-Private"); privateConfig.getProperty("k1", "default value"); //NS-Public Config publicConfig = ConfigService.getConfig("NS-Public"); publicConfig.getProperty("k4", null); // k4 = v5 publicConfig.getProperty("k6", null); // k6 = v6 publicConfig.getProperty("k7", null); // k7 = v7
//application Config appConfig = ConfigService.getAppConfig(); appConfig.getProperty("k1", null); // k1 = v12 appConfig.getProperty("k2", null); // k2 = null appConfig.getProperty("k3", null); // k3 = v33 //NS-Private,因爲沒有NS-Private Namespace 因此獲取到default value Config privateConfig = ConfigService.getConfig("NS-Private"); privateConfig.getProperty("k1", "default value"); //NS-Public,公共類型的Namespace,任何項目均可以獲取到 Config publicConfig = ConfigService.getConfig("NS-Public"); publicConfig.getProperty("k4", null); // k4 = v5 publicConfig.getProperty("k6", null); // k6 = v6 publicConfig.getProperty("k7", null); // k7 = v7
以上代碼例子中能夠看到,在客戶端Namespace映射成一個Config對象。Namespace配置變動的監聽器是註冊在Config對象上。
因此在應用A中監聽application的Namespace代碼以下:
Config appConfig = ConfigService.getAppConfig(); appConfig.addChangeListener(new ConfigChangeListener() { public void onChange(ConfigChangeEvent changeEvent) { //do something } })
在應用A中監聽NS-Private的Namespace代碼以下:
Config privateConfig = ConfigService.getConfig("NS-Private"); privateConfig.addChangeListener(new ConfigChangeListener() { public void onChange(ConfigChangeEvent changeEvent) { //do something } })
在應用A、應用B、應用C中監聽NS-Public的Namespace代碼以下:
Config publicConfig = ConfigService.getConfig("NS-Public"); publicConfig.addChangeListener(new ConfigChangeListener() { public void onChange(ConfigChangeEvent changeEvent) { //do something } })