因为Spring Cloud Config需要配置一些东西才能热加载配置,而且没有图形界面,也没有灰度发布,诸多原因再加上Apollo开源了,所以很多公司还是比较青睐Apollo,所以今天花了半天时间研究了一下,试了一下本地模式,感觉还是挺不错的,废话不多说了。官网传送门
当前最新版本为Apollo 1.6.1-Release,老规矩找个喜欢的文件夹clone。
// clone source code git clone https://github.com/ctripcorp/apollo.git // compile source code cd apollo/ mvn install -Dmaven.test.skip=true mvn idea:idea 或 mvn eclipse:eclipse想让Apollo跑起来需要配置最基础的3个模块,config、admin、portal,配置数据库信息和apollo-meta,我是用的本地MySQL 5.7。
在script下面的sql文件夹有两个sql文件,分别是config和portal需要用到的表,直接打开客户端运行脚本就可以了,不用多做介绍,执行完之后准备下一步,修改配置文件。
3个工程的配置文件需要修改加上数据库配置
# application.yml datasource: url: jdbc:mysql://localhost:3306/apolloconfigdb?characterEncoding=utf8 username: root password: 888888 # apollo-env.properties因为我只配置了dev,所以把其他的注释掉了 local.meta=http://localhost:8080 dev.meta=http://localhost:8080 #dev.meta=${dev_meta} #fat.meta=${fat_meta} #uat.meta=${uat_meta} #lpt.meta=${lpt_meta} #pro.meta=${pro_meta}源码中有demo部分,但不是我们常用的形式,所以就不以源码demo说了,我们IDEA创建一个最最最基础的Spring Boot project,添加上spring-boot-starter-web,和apollo-client,比较直观。
添加maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.6.0</version> </dependency> 添加application.yml:添加application.yml配置,注意application-name和app-id,要与apollo保持一致。虽然application-name不一致也不影响,但是还是建议统一一下比较好。因为Apollo使用了8080,所以我这里改成8888。 server: port: 8888 spring: application: name: ddd-demo apollo: bootstrap: eagerLoad: enabled: true enabled: true namespaces: application meta: http://localhost:8080 app: id: ddd配置文件中的namespaces与下图对应,可以添加多个以英文逗号隔开。
编写配置类:我这边用了两种方式来获取配置,一种是直接在需要的地方@Value,另一种是配置类。 import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import lombok.Data; @Data @Configuration public class TestApolloConfig { @Value("${apollo}") private String apollo; } 编写Controller:然后写了一个Controller,方便测试 @RestController @RequestMapping("apollo") public class ApolloController { @Value("${apollo}") private String apollo; @Resource private TestApolloConfig testApolloConfig; @GetMapping("test") public String test() { String apollo1 = testApolloConfig.getApollo(); return "TestApolloConfig:" + apollo1 + ";@Value:" + this.apollo; } } 启动完成 开始访问:http://localhost:8888/apollo/test 结果是对的,现在修改一下看会不会实时生效。修改配置项 -> 保存 -> 重新发布 刷新一下http://localhost:8888/apollo/test,成功。最简单的实践完成了,看了一下客户端更新配置的源码,远程获取配置的核心类RemoteConfigRepository,在构造的时候启动了schedulePeriodicRefresh,周期性获取,默认间隔实践是2s,在ConfigUtil中默认。 private long longPollingInitialDelayInMills = 2000;//2 seconds 后面专门再写一篇博客简单分析一下原理,Apollo配置动态加载的核心思路还是比较清晰的。
// 构造时初始化了一堆东西 public RemoteConfigRepository(String namespace) { m_namespace = namespace; m_configCache = new AtomicReference<>(); m_configUtil = ApolloInjector.getInstance(ConfigUtil.class); m_httpUtil = ApolloInjector.getInstance(HttpUtil.class); m_serviceLocator = ApolloInjector.getInstance(ConfigServiceLocator.class); remoteConfigLongPollService = ApolloInjector.getInstance(RemoteConfigLongPollService.class); m_longPollServiceDto = new AtomicReference<>(); m_remoteMessages = new AtomicReference<>(); m_loadConfigRateLimiter = RateLimiter.create(m_configUtil.getLoadConfigQPS()); m_configNeedForceRefresh = new AtomicBoolean(true); m_loadConfigFailSchedulePolicy = new ExponentialSchedulePolicy(m_configUtil.getOnErrorRetryInterval(), m_configUtil.getOnErrorRetryInterval() * 8); gson = new Gson(); this.trySync(); this.schedulePeriodicRefresh(); this.scheduleLongPollingRefresh(); }