转载于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 } })