随着java技术的发展,分布式,集群一步步的走过来,java的配置是越来越繁琐了,而且多个节点的话也需要每个节点单独配置,java生态环境中各个大佬也在不断的优化解决这些问题,首先是由springboot开始兴起的“约定优于配置”这一概念,简化了大量配置,使得开发变得更有效率,只需配置与一般做法不同的即可,然后就是随着目前主流的开发流程分开发,测试,预发布,生产,几步,我们开发的项目需要走完这几个环境才能正式的上线给用户使用,这其中每个环境的配置都不一样,并且每个项目还有多个节点(且数目不定,随时可能添加),这给我们队配置的维护带来了很大的不变,基于此,近年来,有了分布式配置中心这一概念的产生,springcloud自带的spring config ,百度的disconf,阿里的Diamond,今天我们介绍的是携程的apollo,它也是基于springcloud的注册中心eureka
一、简介
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
官方github:https://github.com/ctripcorp/apollo
作者对Apollo对介绍:https://github.com/ctripcorp/apollo/wiki/Apollo配置中心介绍
apollo其实是很多独特的优势的,比如配置修改实时生效,灰度发布 ,发布与回滚等。
二、服务端的部署
服务端的代码只需从git上下载下来,按官方文档初始化数据库,更改配置即可,本篇主要阐述客户端的操作
三、java客户端的配置(集成于springcloud)
使用配置中心配置信息
maven引入上面步骤编译打包成功的apollo-core和apollo-client包:
<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-core</artifactId> <version>0.11.0-SNAPSHOT</version> </dependency> <dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>0.11.0-SNAPSHOT</version> </dependency>
然后配置appid和apollo中心的地址(使用springcloud时配置为eureka的地址待研究)这里有两种方法可以配置,
第一在properties配置文件中直接添加配置
//该项木的标识,即注册到apollo配置中心上的名字 app.id=demo //环境信息,apollo服务端默认有dev,fat,pro等,也可在服务端自定义 env=DEV
//服务端地址
dev.meta=http://192.168.0.1:8018
第二,可以通过jvm参数来完成配置,添加如下jvm参数
-Denv=YOUR-ENVIRONMENT -Ddev_meta=http://192.168.0.1:8018
测试
添加一个测试的类DemoConfiguration,主要是添加注解@EnableApolloConfig,启用apollo的配置,当然配置中心要有下面配置的配置信息:
@Configuration @EnableApolloConfig public class DemoConfiguration { @Value("${demo}") private String demo; }
四、apollo的本地缓存
在客户端连不上服务端时,他会使用上一次从服务端获得的配置,该配置放于
Mac/Linux: /opt/data/{appId}/config-cache
Windows: C:\opt\data{appId}\config-cache
五、监听修改配置
apollo的配置更新是实时推送的,但是我们采用配置有时是会初始化一些东西的,此时需要监听配置的变化来实时的做一些切换或重新加载的策略,apollo也为我们提供了这样的接口
Config config = ConfigService.getAppConfig(); config.addChangeListener(new ConfigChangeListener() { @Override public void onChange(ConfigChangeEvent changeEvent) { 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())); } } });