我不喜欢跟人沟通,人心会变,人心复杂。而电脑则不一样,电脑显示有bug那一定是我错了!
一:Apollo配置中心的介绍
GitHub地址: https://github.com/ctripcorp/apollo
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。
Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
-
统一管理不同环境、不同集群的配置
- Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
- 同一份代码部署在不同的集群,可以有不同的配置,比如zk的地址等
- 通过命名空间(namespace)可以很方便的支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
- 配置界面支持多语言(中文,English)
-
配置修改实时生效(热发布)
- 用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序。
-
版本发布管理
- 所有的配置发布都有版本概念,从而可以方便的支持配置的回滚。
-
灰度发布
- 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例。
-
权限管理、发布审核、操作审计
- 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
- 所有的操作都有审计日志,可以方便的追踪问题。
-
客户端配置信息监控
- 可以方便的看到配置在被哪些实例使用
-
提供Java和.Net原生客户端
- 提供了Java和.Net的原生客户端,方便应用集成
- 支持Spring Placeholder,Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
- 同时提供了Http接口,非Java和.Net应用也可以方便的使用
-
提供开放平台API
- Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。
- 不过Apollo出于通用性考虑,对配置的修改不会做过多限制,只要符合基本的格式就能够保存。
- 在我们的调研中发现,对于有些使用方,它们的配置可能会有比较复杂的格式,如xml, json,需要对格式做校验。
- 还有一些使用方如DAL,不仅有特定的格式,而且对输入的值也需要进行校验后方可保存,如检查数据库、用户名和密码是否匹配。
- 对于这类应用,Apollo支持应用方通过开放接口在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
-
部署简单
- 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
- 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
- Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
基础模型
配置中心的架构设计文档:https://github.com/ctripcorp/apollo/wiki/Apollo%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83%E8%AE%BE%E8%AE%A1
- 用户在配置中心对配置进行修改并发布
- 配置中心通知Apollo客户端有配置更新
- Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用
多环境高可用部署图
Apollo配置中心架构剖析
官方地址:https://mp.weixin.qq.com/s/-hUaQPzfsl9Lm3IqQW3VDQ
具体更详细的信息,官方文档也描述的很清楚,可以去GitHub上查看
二:Apollo配置中心的搭建
1、首先下载安装包
下载地址:https://github.com/ctripcorp/apollo/releases
下载adminService,configService,portal三个安装包,解压得到的目录都是相同的,主要有jar包,conf文件,启动脚本
因为portal和configService需要数据库,所以还需要下载两个sql文件,在此提供下载地址:https://github.com/nobodyiam/apollo-build-scripts/tree/master/sql, 正常每个环境都单独有一套adminService和configService, 共用一个portal客户端. 我先安装dev环境,所以先在dev的数据库执行这两个脚本,会生成两个数据库.
2、安装启动
本次安装采用两台虚拟机,一台安装portal客户端,一台安装dev环境(adminService和configService),如下:
IP | 部署应用 | 路径 |
192.168.159.128 | portal客户端 | /data/apolloportal |
192.168.159.131 | adminService和configService | /data/apolloconfig /data/apolloadmin |
先在131机器上修改configService的数据库配置:
vim /data/apolloconfig/config/application-github.properties
再修改131机器 上adminservice的数据库配置:
vim /data/apolloadmin/config/application-github.properties
注:adminService和configService(Mate Server)的数据库是同一个数据库
进入scrpts文件下中,含有startup.sh和shutdown.sh (若不是可执行文件需要先将这两个文件改成可执行文件,修改命令:
chmod +x startup.sh shutsowm.sh 执行之后,这两个文件的颜色会变成绿色) ,接下来就可以启动的,启动顺序是:先启动
configService再启动adminService(configService中封装了Eureka注册中心),启动后访问
启动adminService
接下来需要启动portal客户端
同上,先修改数据库连接,然后再修改apollo-evn.properties配置中的环境配置,指定mate service的地址,也就是上面安装的地址,对应
下图的dev.mate=131....(下图ip地址有误)
然后启动portal,在浏览器中访问, 默认账号:apollo 密码: admin
3、使用portal客户端
首先我们需要理解的就是项项目、环境、集群三者之间的关系,一个项目也就是我们所说的一个应用(服务),每个项目都会
对应不同的环境,比如开发环境(dev)、测试环境(test)、用户环境(uat)、生产环境(prod),每个项目在不同的环境中,可能存在不同的数量,尤其是在生产环境中,每个项目(服务)可能会搭建集群用来达到高可用的目的,正常每个项目(服务)中集群都是共用一个配置,但是对于一些特殊的,比如服务部署是按照地区来的,比如每个地区都有不同的配置,那么此时就可以在portal中添加集群来达到需求。所以项目包含环境,环境包含集群。
系统参数的配置:主要是在界面中修改数据库中的一些参数,如下
创建项目:如下
当我们创建完成后,可以看到,环境列表中只有DEV环境,这是因为我们数据库中环境只设置了一个dev(默认),而且在启动portal客户端是也就指定了dev的mate Server的地址,有关多环境的处理,后面会讲解,而且默认的命名空间是application(,有关命名空间的理解,可以去官网去查看。), 在实际开发中,一般都会建立一个公共的项目,里面存放一些公共的namespace,然后各个项目需要用到,就可以关联公共空间的namespace,如果需要覆盖公共空间的某一项配置,直接在此项目中进行覆盖,有关操作如下截图。
在创建namespace时,如果是公共的namespace,那么默认是properties文件,如果是私有的namespace,会有多种类型的配置,如yml、xml等。添加配置除了一个一个添加(如下图)外,还可以批量添加,直接将配置复制到文本中就可以了。
批量添加:
好了,在此有关客户端的具体使用就不再过多描述了,有关于具体的操作,也可参照官网查看:https://github.com/ctripcorp/apollo/wiki/Apollo%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97
三:Apollo多环境的配置
关于多环境的配置,其实配置起来也很简单,为了方便,在此我只增加一个test环境,
ip | 服务 | ||
192.168.159.128 | portal客户端 | /data/apolloportal | |
192.168.159.131 | DEV环境 adminService和configService |
/data/apolloconfig /data/apolloadmin |
|
192.168.159.132 | TEST环境 adminService和configService |
/data/apolloconfig /data/apolloadmin |
将adminservice和configservice在132机器上搭建,主要修改的配置是数据库,正常开发中,每个环境都会有单独的数据库服务,为了方便,我只是修改了configservice的数据库名,如图,然后启动adminservice和configservice
然后将test环境的数据库名改成这个即可,然后在portal数据库中的环境配置,需要增加test的环境,如下
然后在portal服务的环境配置文件中,需要配置上test环境的mate server地址(IP地址可能有误)
然后重新启动portal服务,登陆后会提示缺少环境,在左边的列表中会有一个添加缺失环境(具体名称不记得了)按钮,点击即可,会得到如下图...在添加新的环境时,注意的是需要现在数据库中添加这个配置,然后mate server添加地址,然后重新启动...
四:Apollo高可用搭建
在生产环境中,往往一套adminservice和configservice是不安全的,所以就需要高可用环境的搭建.由于机器有限,我在此就搭建dev环境的高可用,来模拟生产环境的搭建,其实道理都是一样的.
ip | 服务 | ||
192.168.159.128 | portal客户端 | /data/apolloportal | |
192.168.159.131 | DEV环境 adminService和configService |
/data/apolloconfig /data/apolloadmin |
|
192.168.159.132 | DEV环境 adminService和configService |
/data/apolloconfig /data/apolloadmin |
我将原来的test环境的环境改成dev环境,那么就需要和131机器上连的是同一个数据库,修改下即可,还需要修改数据库中的eureka的配置,
将两台机器的eureka地址填写下,同理如果还有第三台高可用服务,再添加一个即可,然后启动后访问eureka服务,你会看到如下图,就说明搭建成功了,如果有错误,可查看启动日志,默认在/opt/logs/XXX路径下......
然后还需要修改portal中的mate server地址,注释掉test的mate server ,将dev的mate server 地址 加上132的地址,用逗号分割.然后重新启动mate server.登陆
可查看portal可系统信息如下:
验证高可用:
当所有的adminservice 和 configservice 都宕机,只要本地启动过的项目,启动是没问题的,因为读取的是本地的缓存过的配置,当我们删除本地的配置,就启动不了了。
当所有的configservice都宕机,adminservice只要启动,就可以发布配置,当configservice启动后,项目还可以读取到最新的配置,此处主要原因是发布使用的是消息队列异步发生,adminservice是发生端,configservice是消费端。
五:Apollo集成Spring boot
Apollo也支持多种集成环境,在此给出Spring boot 集成apollo的使用,其它的环境可查看官网....
1、引入maven依赖
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-core</artifactId>
<version>1.1.0</version>
</dependency>
2、再启动类上增加apollo的自动配置注解
3、配置文件
Apollo官方提供多种集成配置,如下图:
‘
在此我选择第8种配置,在resource目录下新建一个 apollo-env.properties文件,里面主要是描述了 mate server的地址
注意:如果是高可用环境,多个地址之间用逗号分割
然后在application.properties/yml中配置 appid(portal新建项目时填写的), 注意的是,需要填写需要的namespace,要不然会读取不到配置的. cacheDir是apollo客户端读取到的配置文件存放到本地的路径, cluster是指定集群环境,默认的default环境, 在开发中此参数应该放在启动参数中设定.
关于autoUpdateInjectedSpringProperties的配置介绍如下
启动参数中设置 指定的项目环境,(集群也建议在此设定)
配置好后,我们就可以启动项目了,
有关测试,在此就不在多描述了.
本地缓存路径
启动后查看/data下
apollo 使用@ConfigurationProperties 使用失效解决
熟悉Spring cloud config的应该知道,在项目中有些自定义配置可以通过@ConfigurationProperties来完成, 如果加上@RefreshScope注解,就表示其含有自动刷新的功能,就比如我在配置文件中修改了配置,然后调用下api,项目中会感知到的配置的变更,从而获取到的也是最新的配置,那么apollo是如果也需要达到此效果(其读取配置的客户端就可以,但是如果非要使用ConfigurationProperties注解),就需要额外加上一些配置,下面贴出代码:
package com.gillion.worldex.bms.config;
import com.ctrip.framework.apollo.core.ConfigConsts;
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.scope.refresh.RefreshScope;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
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 {
private ApplicationContext applicationContext;
@Autowired
private RefreshScope refreshScope;
//这里指定Apollo的namespace,非常重要,如果不指定,默认只使用application
@ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION})
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;
}
}
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@Data
@ConfigurationProperties(prefix = "worldex.add")
public class TestPropertiesConfg {
private String test2;
private String test1;
}
经过以上,可以实现自动刷新,当在portal上修改了配置后重新发布下,即可在控制台看到如下日志。
至此,有关于apollo的配置就完成了,其官方的文档写的也是很详细,建议大家去阅读参考官方文档.
对此篇文章,如有错误之处或者更高见解,欢迎大家留言!!!!!!