Java 1.8+
Guava 20.0+
AppId 是应用的身份信息,是从服务端获取配置的一个重要信息。
有如下几种方式设置,按照优先级从高到低分别为:
1、System Property
Apollo 0.7.0+ 支持通过 System Property 传入 app.id 信息。
-Dapp.id=YOUR-APP-ID
2、System Environment
Apollo 1.4.0+ 支持通过操作系统的 System Envinronment APP_ID
来传入 app.id 信息。
APP_ID=YOUR-APP-ID
3、application.properties
Apollo 1.0.0+ 支持通过 Spring Boot 的 application.properties 文件配置。
该配置方式不适用于多个 war 包部署在同一个 tomcat 的使用场景。
app.id=YOUR-APP-ID
4、app.properties
在 classpath:/META-INF/app.properties 文件中指定配置。
app.id=YOUR-APP-ID
Apollo Meta Server 的地址。按照优先级从高到低分别为:
1、System Property
可以通过 Java 的 System Property 指定。
-Dapollo.meta=http://config-service-url
如果是运行 jar 文件,可以通过如下格式指定。
java -Dapollo.meta=http://config-service-url -jar xxx.jar
也可以通过程序指定。
System.setProperty("apollo.meta", "http://config-service-url");
2、application.properties 或者 bootstrap.properties
该配置方式不适用于多个 war 包部署在同一个 tomcat 的使用场景。
apollo.meta=http://config-service-url
3、System Environment
通过操作系统的 System Environment
APOLLO_META=http://config-service-url
4、server.properties
对于 Mac/Linux,默认文件位置为:/opt/settings/server.properties
对于 Windows,默认文件位置为:C:\opt\settings\server.properties
apollo.meta=http://config-service-url
5、app.properties
在 classpath:/META-INF/app.properties
文件中指定。
apollo.meta=http://config-service-url
6、System Property ${env}_meta
-Ddev_meta=http://config-service-url
7、System Environment ${ENV}_META
DEV_META=http://config-service-url
8、apollo-env.properties
程序的 classpath 下,或者 Spring Boot 应用的 config 目录下。
dev.meta=http://1.1.1.1:8080
fat.meta=http://apollo.fat.xxx.com
uat.meta=http://apollo.uat.xxx.com
pro.meta=http://apollo.xxx.com
Apollo 客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或者网络不通的时候,依然能够从本地恢复配置,不影响应用正常使用。
本地缓存的默认目录如下:
/opt/data/{appId}/config-cache
C:\opt\data\{appId}\config-cache
本地配置文件会以下面的文件名格式放置于本地缓存路径下:
{appId}+{cluster}+{namespace}.properties
1.0.0 版本支持如下方式自定义缓存路径,按照优先级从高到低分别为:
1、System Property
可以通过 Java 的 System Property apollo.cache-dir
(1.9.0 +)、apollo.cacheDir
(1.9.0 之前)来指定。
在Java程序启动脚本中,可以指定 -Dapollo.cache-dir=/opt/data/some-cache-dir
(1.9.0 +) 或者 apollo.cacheDir=/opt/data/some-cache-dir
(1.9.0 之前)
如果是运行 jar 文件,需要注意格式是 java -Dapollo.cache-dir=/opt/data/some-cache-dir -jar xxx.jar
(1.9.0 +) 或者 java -Dapollo.cacheDir=/opt/data/some-cache-dir -jar xxx.jar
(1.9.0 之前)
也可以通过程序指定,如 System.setProperty("apollo.cache-dir", "/opt/data/some-cache-dir");
(1.9.0 +) 或者 System.setProperty("apollo.cacheDir", "/opt/data/some-cache-dir");
(1.9.0 之前)
2、application.properties、bootstrap.properties
指定 apollo.cache-dir=/opt/data/some-cache-dir
(1.9.0 +) 或者 apollo.cacheDir=/opt/data/some-cache-dir
(1.9.0 之前)
3、System Environment
APOLLO_CACHE_DIR
(1.9.0 +) 或者 APOLLO_CACHEDIR
(1.9.0 之前)
4、server.properties
指定 apollo.cache-dir=/opt/data/some-cache-dir
(1.9.0 +) 或者 apollo.cacheDir=/opt/data/some-cache-dir
(1.9.0 之前)
/opt/settings/server.properties
C:\opt\settings\server.properties
目前 env 支持 DEV、FAT、UAT、PRO 几个值。
可以通过如下三种方式进行配置。
1、System Property
env
来指定环境。-Denv=YOUR-ENVIRONMENT
java -Denv=YOUR-ENVINRONMENT -jar xxx.jar
2、System Environment
ENV
来指定。3、通过配置文件
/opt/settings/server.properties
C:\opt\settings\server.properties
Apollo 支持配置按照集群划分,也就是对于一个 appId 和一个环境,对于不同集群可以有不同的配置。
1.0.0 版本开始支持以下方式配置,按照优先级从高到低分别为:
1、 System Property 指定 apollo.cluster
apollo.cluster
来指定-Dapollo.cluster=SomeCluster
java -Dapollo.cluster=SomeCluster -jar xxx.jar
System.setProperty("apollo.cluster", "SomeCluster");
2、application.properties、bootstrap.properties 文件中指定 apollo.cluster=SomeCluster
3、System Property 指定 idc
idc
来指定环境-Didc=xxx
java -Didc=xxx -jar xxx.jar
4、System Environment 指定 idc
IDC
来指定
5、server.properties
server.properties
配置文件中指定 idc=xxx
/opt/settings/server.properties
C:\opt\settings\server.properties
Cluster Precedence(集群顺序)
1、如果 apollo.cluster 和idc 同时指定:
2、如果只指定了 apollo.cluster:
3、如果只指定了 idc:
4、如果 apollo.cluster 和 idc 都没有指定:
默认情况下,apollo client 内存中的配置存放在 Properties 中,不会刻意保持和页面上看到的顺序一致,对绝大部分的场景是没有影响的。不过有些场景会强依赖配置项的顺序(如 Spring Cloud Zuul 的路由规则),针对这种情况,可以开启 OrderedProperties 特性来使得内存中的配置顺序和页面上看到的一致。
配置方式按照优先级从高到低分别为:
1、System Property
apollo.property.order.enable
来指定java -Dapollo.property.order.enable=true -jar xxx.jar
System.setProperty("apollo.property.order.enable", "true");
2、application.properties 或者 bootstrap.properties 文件中指定 apollo.property.order.enable=true
3、app.properties
classpath:/META-INF/app.properties
指定apollo.property.order.enable=true
Apollo 从 1.6.0 版本开始增加访问密钥机制,从而只有经过身份验证的客户端才能访问敏感配置。如果应用开启了访问密钥,客户端需要配置密钥,否则无法获取配置。
配置方式按照优先级从高到低分别为:
1、System Property
apollo.access-key.secret
(1.9.0+) 或者 apollo.accesskey.secret
(1.9.0之前)来指定java -Dapollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719 -jar xxx.jar
(1.9.0+) 或者 java -Dapollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719 -jar xxx.jar
(1.9.0之前)System.setProperty("apollo.access-key.secret", "1cf998c4e2ad4704b45a98a509d15719");
(1.9.0+) 或者 System.setProperty("apollo.accesskey.secret", "1cf998c4e2ad4704b45a98a509d15719");
(1.9.0之前)2、application.properties 或者 bootstrap.properties
apollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719
(1.9.0+) 或者 apollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719
(1.9.0之前)3、System Environment
APOLLO_ACCESS_KEY_SECRET
(1.9.0+) 或者 APOLLO_ACCESSKEY_SECRET
(1.9.0之前)来指定4、app.properties
classpath:/META-INF/app.properties
指定apollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719
(1.9.0+) 或者 apollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719
(1.9.0之前)1.8.0 版本开始支持以下方式自定义 server.properties 路径,按照优先级从高到低分别为:
1、System Property
apollo.path.server.properties
来指定。java -Dapollo.path.server.properties=/some-dir/some-file.properties -jar xxx.jar
。System.setProperty("apollo.path.server.properties", "/some-dir/some-file.properties");
2、System Environment
APOLLO_PATH_SERVER_PROPERTIES
来指定在使用 @ConfigurationProperties 注解和存在大量配置项的场景下,Spring 容器的启动速度会变慢。通过开启该配置可以显著提升启动速度,当配置发生变化时缓存会自动清理,默认为 false。
配置方式按照优先级从高到低依次为:
1、System Property
apollo.property.names.cache.enable
来指定。java -Dapollo.property.names.cache.enable=true -jar xxx.jar
。System.setProperty("apollo.property.names.cache.enable", "true");
。2、System Environment
APOLLO_PROPERTY_NAMES_CACHE_ENABLE=true
3、application.properties 或者 bootstrap.properties
apollo.property.names.cache.enable=true
4、app.properties
可以在 classpath:/META-INF/app.properties
指定如下:
apollo.property.names.cache.enable=true
ApolloLabel 是应用的标签信息,是从服务端获取配置的一个重要信息,用于灰度规则的配置。
有如下几种方式设置,按照优先级从高到低分别为:
1、System Property
Apollo 2.0.0+ 支持通过 System Property 传入 apollo.label 信息。
-Dapollo.label=YOUR-APOLLO-LABEL
2、System Environment
Apollo 2.0.0+ 支持通过操作系统的 System Environment 来传入 apollo.label 信息。
APOLLO_LABEL=YOUR-APOLLO-LABEL
3、application.properties
Apollo 2.0.0+ 支持通过 Spring Boot 的 application.properties 文件配置。
该配置方式不适用于多个 war 包部署在同一个 tomcat 的使用场景。
apollo.label=YOUR-APOLLO-LABEL
4、app.properties
在 classpath:/META-INF/app.properties 文件中。
apollo.label=YOUR-APOLLO-LABEL
在 2.1.0 + 版本,apollo.override-system-properties
标识 Apollo 的远程属性是否应该覆盖 Java 的系统属性。默认为 true。
配置方式按照优先级从高到低分别为:
1、System Property
apollo.override-system-properties
来指定。java -Dapollo.override-system-properties=true -jar xxx.jar
。System.setProperty("apollo.override-system-properties", "true");
。2、application.properties 或者 boostrap.properties 文件中指定 apollo.override-system-properties=true
3、app.properties 文件
classpath:/META-INF/app.properties
指定 apollo.override-system-properties=true
。<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.8.0</version>
</dependency>
API 方式是最简单、高效使用使用 Apollo 配置的方式,不依赖 Spring 框架即可使用。
获取命名空间的配置
// 1、获取默认的命名空间的配置
Config config = ConfigService.getAppConfig();
// 2、获取properties格式的命名空间的配置
// String somePublicNamespace = "CAT";
// Config config = ConfigService.getConfig(somePublicNamespace);
// 3、获取yaml/yml格式的命名空间的配置
// Config config = ConfigService.getConfig("application.yml");
// 4、获取其它格式的命名空间的配置
// ConfigFile configFile = ConfigService.getConfigFile("test", ConfigFileFormat.XML);
// String content = configFile.getContent();
String someKey = "someKeyFromDefaultNamespace";
String someDefaultValue = "someDefaultValueForTheKey";
String value = config.getProperty(someKey, someDefaultValue);
通过 Config 的 getProperty 方法可以获取到指定属性对应的属性值。
监听配置变化事件
Config config = ConfigService.getAppConfig();
config.addChangeListener(new ConfigChangeListener() {
@Override
pubic void onChange(ConfigChangeEvent changeEvent) {
System.out.println("Changes for namespace " + changeEvent.getNamespace());
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
}
}
});
希望配置发生变化时得到通知。通过 Config 的 addChangeListener 方法添加一个 ConfigChangeListener 监听器。
可以在代码中直接使用,如:@Value("${someKeyFromApollo:someDefaultValue}")
。
也可以在配置文件中使用,如:spring.datasource.url:${someKeyFromApollo:someDefaultValue}
。
甚至可以直接托管 Spring 中的配置。如:在 Apollo 中直接配置 spring.datasource.url=jdbc:mysql://localhost:3306/somedb
。
支持 Spring Boot 的 @ConfigurationProperties
方式。
也支持结合 API 方式使用,如:@ApolloConfig private Config config;
。
注入默认的命名空间的配置到 Spring 中
@Configuration
@EnableApolloConfig
public class AppConfig {
}
注入多个命名空间的配置到 Spring 中
@Configuration
@EnableApolloConfig({"FX.apollo", "application.yml"})
public class AnotherAppConfig {
}
注入多个命名空间的配置到 Spring 中,并且指定顺序
在 @EnableApolloConfig 注解中的 order 属性指定顺序,值越小则顺序越靠前。
@Configuration
@EnableApolloConfig(order = 2)
public class AppConfig {
}
@Configuration
@EnableApolloConfig(value = {"FX.apollo", "application.yml"}, order = 1)
public class AnotherAppConfig {
}
额外支持通过 application.properties / bootstrap.properties 进行配置,该方式可以使配置在更早的阶段注入,比如使用 @ConditionalOnProperty
的场景或者有一些 spring-boot-starter 在启动阶段就需要读取配置然后做一些事情。
# 启动阶段注入application命名空间的配置
apollo.bootstrap.enabled = true
也支持注入多个命名空间的配置。
# 启动阶段注入application,FX.apollo,application.yml命名空间的配置
apollo.bootstrap.enabled = true
apollo.bootstrap.namespaces = application,FX.apollo,application.yml
可以让 Apollo 的加载顺序在日志系统之前,比如希望把日志相关的配置(logging.level.root=info
或者 logback-spring.xml 中的参数)也交给 Apollo 管理。
# 启动阶段注入application命名空间的配置
apollo.bootstrap.enabled = true
# 让 Apollo 的加载顺序在日志系统之前
apollo.bootstrap.eagerLoad.enabled = true
详细内容参考官方文档 - Spring Boot Config Data Loader
在 Spring 环境中,可以使用占位符的形式注入配置,如:${someKey:someDefaultValue}
。
建议在实际使用时尽量给出默认值,以免由于 key 没有定义导致运行时错误。
从 v0.10.0 版本开始,支持占位符的运行时自动更新。想要关闭占位符的运行时自动更新,可以选择如下任意方法:
1、通过设置系统参数,如启动时传入 -Dapollo.autoUpdateInjectedSpringProperties=false
。
2、通过设置 META-INF/app.properties 中的 apollo.autoUpdateInjectedSpringProperties
属性,如:
app.id = SampleApp
apollo.autoUpdateInjectedSpringProperties = false
假设 TestXmlBean 中有两个配置项需要注入。
public class TestXmlBean {
private int timeout;
private int batch;
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public void setBatch(int batch) {
this.batch = batch;
}
public int getTimeout() {
return timeout;
}
public int getBatch() {
return batch;
}
}
在 xml 中使用如下方式进行定义。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:apollo="http://www.ctrip.com/schema/apollo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd">
<apollo:config/>
<bean class="com.ctrip.framework.apollo.spring.TestXmlBean">
<property name="timeout" value="${timeout:100}"/>
<property name="batch" value="${batch:200}"/>
</bean>
</beans>
假设 TestJavaConfigBean 中,需要注入两个属性。
public class TestJavaConfigBean {
@Value("${timeout:100}")
private int timeout;
private int batch;
@Value("${batch:200}")
public void setBatch(int batch) {
this.batch = batch;
}
public int getTimeout() {
return timeout;
}
public int getBatch() {
return batch;
}
}
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public TestJavaConfigBean javaConfigBean() {
return new TestJavaConfigBean();
}
}
Spring Boot 提供了 @ConfigurationProperties 注解用于将配置注入到 bean 对象中。
Apollo 也支持这种方式。
@ConfigurationProperties(prefix = "redis.cache")
public class SampleRedisConfig {
private int expireSeconds;
private int commandTimeout;
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
public void setCommandTimeout(int commandTimeout) {
this.commandTimeout = commandTimeout;
}
}
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public SampleRedisConfig sampleRedisConfig() {
return new SampleRedisConfig();
}
}
需要注意的是,@ConfigurationProperties
如果需要在配置发生变化时自动更新注入的值,需要配合使用 EnvironmentChangeEvent 或者 RefreshScope,可以参考 EnvironmentChangeEvent 样例、RefreshScope 样例1、RefreshScope 样例2。
Apollo 在 Spring 环境中,提供了如下三个注解:
@ApolloConfig
:用来自动注入 Config 对象。@ApolloConfigChangeListener
:用来自动注册 ConfigChangeListener。@ApolloJsonValue
:用来将配置的 json 字符串自动注入为对象。public class TestApolloAnnotationBean {
@ApolloConfig
private Config config; // 注入“application”命名空间的配置
@ApolloConfig("application")
private Config anotherConfig; // 注入“application”命名空间的配置
@ApolloConfig("FX.apollo")
private Config yetAnotherConfig; // 注入“FX.apollo”命名空间的配置
@ApolloConfig("application.yml")
private Config ymlConfig; // 注入“application.yml”命名空间的配置
/**
* jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue("${jsonBeanProperty:[]}")
private List<JsonBean> anotherJsonBeans; // 将“jsonBeanProperty”字符串解析并注入
@Value("${batch:100}")
private int batch;
@ApolloConfigChangeListener
public void someOnChange(ConfigChangeEvent changeEvent) { // 监听“application”命名空间的配置的变化
if (changeEvent.isChanged("batch")) {
this.batch = config.getIntProperty("batch", 100);
}
}
@ApolloConfigChangeListener({"application", "FX.apollo", "application.yml"})
public void yetAnotherOnChange(ConfigChangeEvent changeEvent) { // 监听“application”、“FX.apollo”、“application.yml”命名空间的配置的变化
}
}
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public TestApolloAnnotationBean testApolloAnnotationBean() {
return new TestApolloAnnotationBean();
}
}