<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.5.1</version> </dependency>
注:
如果是有内部多个应用同时要使用Apollo,可以将Apollo封装到一个单独的Jar中,供这些应用引入。且可以将各环境(DEV、UAT、TEST、PRD)Meta Server写在名为apollo-env.properties配置文件中,如下所示:
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
并将其放到classpath下,这些Meta Server就是各环境的默认值,后续也可以通过在java的启动参数-Dapollo.meta=metaServerHost,或者spring boot的配置文件application.properties通过指定apollo.meta=metaServerHost等方式,进行修改。
然后在java启动参数只需要通过-Denv=DEV等参数,apollo就会选择特定环境的Meta Server。
详见: apollo meta server的配置
Apollo本身对参数具有热更新的功能,但是Apollo中配置Key一定要是application.properties或application.yml中的key,而不是引入了其它配置文件中的key,否则热更新不会起效,以下举示例说明。
项目中包括了两个配置文件:
application-config.properties application.properties
内容分别如下:
application-config.properties
TEST_KEY=It's a test value
application.properties
spring.profile.active = config test.key=${TEST_KEY:default_value}
如果在apollo中配置项是
TEST_KEY=new value
那修改该配置项TEST_KEY,应用虽然可以收到配置项修改的通知,但是引入test.key的对象中的属性值不会发生变化,只有重启应用才会生效。
为了让配置即时生效,Apollo中的配置项应该是application.properties中的test.key,修改配置项test.key的值,则引入test.key的对象中的属性值就会即时生效。
针对使用了注解@ConfigurationProperties的配置注入方式,如下示例类:
@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; } }
针对这种Bean, 需要使用spring cloud的EnvironmentChangeEvent和RefreshScope ,实现方式如下:
1)依赖spring cloud context,如:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> <version>2.0.4.RELEASE</version><!--版本根据实际场景而定--> </dependency>
2)在spring boot的配置文件中增加如下配置项:
spring.boot.enableautoconfiguration=true
3)实现ApplicationContextAware
import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.cloud.context.scope.refresh.RefreshScope; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; /** * apollo 自动刷新 * * @author qubianzhong * @Date 20:32 2019/11/11 */ @Component @Slf4j public class ApolloRefreshConfig implements ApplicationContextAware { ApplicationContext applicationContext; @Autowired RefreshScope refreshScope; //这里指定Apollo的namespace,非常重要,如果不指定,默认只使用application @ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION,"business","everything"}) public void onChange(ConfigChangeEvent changeEvent) { for (String changedKey : changeEvent.changedKeys()) { log.info("apollo changed namespace:{} Key:{} value:{}", changeEvent.getNamespace(), changedKey, changeEvent.getChange(changedKey)); } refreshProperties(changeEvent); } public void refreshProperties(ConfigChangeEvent changeEvent) { this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys())); refreshScope.refreshAll(); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
java / -Dapollo.autoUpdateInjectedSpringProperties=true / -Dapp.id=apollo-demo / -Denv=DEV / -Dapollo.meta=http://192.168.10.235:8071 / -Dapollo.bootstrap.enabled=true / -Dapollo.bootstrap.eagerLoad.enabled=true / -Dapollo.bootstrap.namespaces=application / -Dapollo.cacheDir=/opt/data/some-cache-dir / -jar apollo-demo.jar
apollo.autoUpdateInjectedSpringProperties:是否自动更新配置,如果不想自动更新则将该值设置为false,默认值为true
app.id:项目的AppId
env:环境设置,测试环境DEV,预发布环境UAT,生产环境PRO,可以通三种方式(启动参数、操作系统环境变量以及配置文件)指定, 详见文档
apollo.meta:apollo服务地址,例如测试环境是http://192.168.10.235:8071
apollo.bootstrap.enabled:启动阶段是否注入配置
apollo.bootstrap.eagerLoad.enabled:是否将apollo的加载放到日志系统的加载之前,这样就可以通过apollo来管理日志相关的配置,如日志级别的设置等,如果为true,则会在这个阶段apollo不会有日志输出
apollo.bootstrap.namespaces:配置项,这里要和阿波罗里面配置的properties文件一一对应,例如阿波罗配置了application.properties、db.properties和dubbo.properties三个配置文件,这里就是设值为application,db,dubbo
apollo.cacheDir:自定义缓存路径
脚本中namespaces的默认值为application,所以默认读取的是阿波罗上application.properties配置文件。
如果参数特别多,或者其他需求,需要添加多个配置文件的话,需要联系运维同学配合修改项目的jenkins配置,修改namespaces参数。正常情况建议只用一个application.properties配置文件
详情参看Apollo Java使用的官方文档: Apollo Java客户端使用指南