搭建apollo还算比较简单,官方文档也非常详细。之前遇到问题在apollo的qq群里咨询,群友很热心,小问题很快就能帮忙解决或者找到解决问题的思路。准备基于《芋道源码》和杨波老师的脚步,对apollo进行更深入一点的了解。
1. 本地运行时环境
- JDK :1.8+
- MySQL :5.6.5+
- Maven
- IntelliJ IDEA
从官方仓库 <https://github.com/ctripcorp/apollo> Fork
出属于自己的仓库<https://github.com/sxyseo/apollo>。为什么要 Fork
?既然开始阅读、调试源码,我们可能会写一些注释,有了自己的仓库,可以进行自由的提交。😈
使用 IntelliJ IDEA
从 Fork
出来的仓库拉取代码。拉取完成后,Maven
会下载依赖包,可能会花费一些时间,耐心等待下。
文档特别详细<https://github.com/ctripcorp/apollo/wiki>,作为新手从文档入手到最后部署,问题不大,结合自己的开发测试生产环境进行一些调整。建议通过Quick Start <https://github.com/ctripcorp/apollo/wiki/Quick-Start> 先行体验一下,有一定的体验后再看源码。官方Apollo开发指南 <https://github.com/ctripcorp/apollo/wiki/Apollo%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97>
2. 创建数据库
Apollo服务端共需要两个数据库:ApolloPortalDB
和ApolloConfigDB
,我们把数据库、表的创建和样例数据都分别准备了sql文件,只需要导入数据库即可。
需要注意的是ApolloPortalDB只需要在生产环境部署一个即可,而ApolloConfigDB需要在每个环境部署一套,如fat、uat和pro分别部署3套ApolloConfigDB。
注意:如果你本地已经创建过Apollo数据库,请注意备份数据。我们准备的sql文件会清空Apollo相关的表。
2.1.1 创建ApolloPortalDB
可以根据实际情况选择通过手动导入SQL或是通过Flyway自动导入SQL创建。
2.1.1.1 手动导入SQL创建
通过各种MySQL客户端导入apolloportaldb.sql即可。
1.3.0版本开始为了支持Flyway,sql位置和命名从之前的
scripts/sql/apolloportaldb.sql
改为了scripts/db/migration/portaldb/V1.0.0__initialization.sql
以MySQL原生客户端为例:
source /your_local_path/portaldb/V1.0.0__initialization.sql
2.1.1.2 通过Flyway导入SQL创建
需要1.3.0及以上版本
- 根据实际情况修改flyway-portaldb.properties中的
flyway.user
、flyway.password
和flyway.url
配置 - 在apollo项目根目录下执行
mvn -N -Pportaldb flyway:migrate
2.1.1.3 验证
导入成功后,可以通过执行以下sql语句来验证:
select `Id`, `Key`, `Value`, `Comment` from `ApolloPortalDB`.`ServerConfig` limit 1;
Id | Key | Value | Comment |
---|---|---|---|
1 | apollo.portal.envs | dev | 可支持的环境列表 |
注:ApolloPortalDB只需要在生产环境部署一个即可
2.1.2 创建ApolloConfigDB
可以根据实际情况选择通过手动导入SQL或是通过Flyway自动导入SQL创建。
2.1.2.1 手动导入SQL
通过各种MySQL客户端导入apolloconfigdb.sql即可。
1.3.0版本开始为了支持Flyway,sql位置和命名从之前的
scripts/sql/apolloconfigdb.sql
改为了scripts/db/migration/configdb/V1.0.0__initialization.sql
以MySQL原生客户端为例:
source /your_local_path/configdb/V1.0.0__initialization.sql
![image-20190405114735506](/Users/abel/Library/Application Support/typora-user-images/image-20190405114735506.png)
2.1.2.2 通过Flyway导入SQL
需要1.3.0及以上版本
- 根据实际情况修改flyway-configdb.properties中的
flyway.user
、flyway.password
和flyway.url
配置 - 在apollo项目根目录下执行
mvn -N -Pconfigdb flyway:migrate
2.1.2.3 验证
导入成功后,可以通过执行以下sql语句来验证:
select `Id`, `Key`, `Value`, `Comment` from `ApolloConfigDB`.`ServerConfig` limit 1;
Id | Key | Value | Comment |
---|---|---|---|
1 | eureka.service.url | <http://127.0.0.1:8080/eureka/> | Eureka服务Url |
注:ApolloConfigDB需要在每个环境部署一套,如fat、uat和
pro分别部署3套ApolloConfigDB
2.1.2.1 从别的环境导入ApolloConfigDB的项目数据
如果是全新部署的Apollo配置中心,请忽略此步。
如果不是全新部署的Apollo配置中心,比如已经使用了一段时间,这时在Apollo配置中心已经创建了不少项目以及namespace等,那么在新环境中的ApolloConfigDB中需要从其它正常运行的环境中导入必要的项目数据。
主要涉及ApolloConfigDB的下面4张表,下面同时附上需要导入的数据查询语句:
- App
- 导入全部的App
- 如:insert into
新环境的ApolloConfigDB
.App
select * from其它环境的ApolloConfigDB
.App
whereIsDeleted
= 0;
- AppNamespace
– 导入全部的AppNamespace
– 如:insert into 新环境的ApolloConfigDB
.AppNamespace
select * from 其它环境的ApolloConfigDB
.AppNamespace
where IsDeleted
= 0;
3. Cluster
– 导入默认的default集群
– 如:insert into 新环境的ApolloConfigDB
.Cluster
select * from 其它环境的ApolloConfigDB
.Cluster
where Name
= ‘default’ and IsDeleted
= 0;
4. Namespace
– 导入默认的default集群中的namespace
– 如:insert into 新环境的ApolloConfigDB
.Namespace
select * from 其它环境的ApolloConfigDB
.Namespace
where ClusterName
= ‘default’ and IsDeleted
= 0;
同时也别忘了通知用户在新的环境给自己的项目设置正确的配置信息,尤其是一些影响面比较大的公共namespace配置。
如果是为正在运行的环境迁移数据,建议迁移完重启一下config service,因为config service中有appnamespace的缓存数据
2.1.3 调整服务端配置
Apollo自身的一些配置是放在数据库里面的,所以需要针对实际情况做一些调整。
2.1.3.1 调整ApolloPortalDB配置
配置项统一存储在ApolloPortalDB.ServerConfig表中,也可以通过管理员工具 - 系统参数
页面进行配置,无特殊说明则修改完一分钟实时生效。
1.apollo.portal.envs – 可支持的环境列表
默认值是dev,如果portal需要管理多个环境的话,以逗号分隔即可(大小写不敏感),如:
DEV,FAT,UAT,PRO
修改完需要重启生效。
注1:一套Portal可以管理多个环境,但是每个环境都需要独立部署一套Config Service、Admin Service和ApolloConfigDB,具体请参考:2.1.2 创建ApolloConfigDB,2.1.3.2 调整ApolloConfigDB配置,2.2.1.2 配置数据库连接信息,另外如果是为已经运行了一段时间的Apollo配置中心增加环境,别忘了参考2.1.2.1 从别的环境导入ApolloConfigDB的项目数据对新的环境做初始化。
注2:只在数据库添加环境是不起作用的,还需要为apollo-portal添加新增环境对应的meta server地址,具体参考:2.2.1.2.4 配置apollo-portal的meta service信息。apollo-client在新的环境下使用时也需要做好相应的配置,具体参考:1.2.2 Apollo Meta Server。
注3:如果希望添加自定义的环境名称,具体步骤可以参考部署&开发遇到的常见问题#42-添加自定义的环境。
注4:1.1.0版本增加了系统信息页面(
管理员工具
->系统信息
),可以通过该页面检查配置是否正确
2.organizations – 部门列表
Portal中新建的App都需要选择部门,所以需要在这里配置可选的部门信息,样例如下:
[{"orgId":"TEST1","orgName":"样例部门1"},{"orgId":"TEST2","orgName":"样例部门2"}]
3.superAdmin – Portal超级管理员
超级管理员拥有所有权限,需要谨慎设置。
如果没有接入自己公司的SSO系统的话,可以先暂时使用默认值apollo(默认用户)。等接入后,修改为实际使用的账号,多个账号以英文逗号分隔(,)。
4.consumer.token.salt – consumer token salt
如果会使用开放平台API的话,可以设置一个token salt。如果不使用,可以忽略。
5.wiki.address
portal上“帮助”链接的地址,默认是Apollo github的wiki首页,可自行设置。
6.admin.createPrivateNamespace.switch
是否允许项目管理员创建private namespace。设置为true
允许创建,设置为false
则项目管理员在页面上看不到创建private namespace的选项。了解更多Namespace
7. configView.memberOnly.envs
只对项目成员显示配置信息的环境列表,多个env以英文逗号分隔。
对设定了只对项目成员显示配置信息的环境,只有该项目的管理员或拥有该namespace的编辑或发布权限的用户才能看到该私有namespace的配置信息和发布历史。公共namespace始终对所有用户可见。
从1.1.0版本开始支持,详见PR 1531
2.1.3.2 调整ApolloConfigDB配置
配置项统一存储在ApolloConfigDB.ServerConfig表中,需要注意每个环境的ApolloConfigDB.ServerConfig都需要单独配置,修改完一分钟实时生效。
1. eureka.service.url – Eureka服务Url
不管是apollo-configservice还是apollo-adminservice都需要向eureka服务注册,所以需要配置eureka服务地址。 按照目前的实现,apollo-configservice本身就是一个eureka服务,所以只需要填入apollo-configservice的地址即可,如有多个,用逗号分隔(注意不要忘了/eureka/后缀)。
需要注意的是每个环境只填入自己环境的eureka服务地址,比如FAT的apollo-configservice是1.1.1.1:8080和2.2.2.2:8080,UAT的apollo-configservice是3.3.3.3:8080和4.4.4.4:8080,PRO的apollo-configservice是5.5.5.5:8080和6.6.6.6:8080,那么:
- 在FAT环境的ApolloConfigDB.ServerConfig表中设置eureka.service.url为:
http://1.1.1.1:8080/eureka/,http://2.2.2.2:8080/eureka/
- 在UAT环境的ApolloConfigDB.ServerConfig表中设置eureka.service.url为:
http://3.3.3.3:8080/eureka/,http://4.4.4.4:8080/eureka/
- 在PRO环境的ApolloConfigDB.ServerConfig表中设置eureka.service.url为:
http://5.5.5.5:8080/eureka/,http://6.6.6.6:8080/eureka/
注1:这里需要填写本环境中全部的eureka服务地址,因为eureka需要互相复制注册信息
注2:如果希望将Config Service和Admin Service注册到公司统一的Eureka上,可以参考部署&开发遇到的常见问题 – 将Config Service和Admin Service注册到单独的Eureka Server上章节
注3:在多机房部署时,往往希望config service和admin service只向同机房的eureka注册,要实现这个效果,需要利用
ServerConfig
表中的cluster字段,config service和admin service会读取所在机器的/opt/settings/server.properties
(Mac/Linux)或C:\opt\settings\server.properties
(Windows)中的idc属性,如果该idc有对应的eureka.service.url配置,那么就只会向该机房的eureka注册。比如config service和admin service会部署到SHAOY
和SHAJQ
两个IDC,那么为了实现这两个机房中的服务只向该机房注册,那么可以在ServerConfig
表中新增两条记录,分别填入SHAOY
和SHAJQ
两个机房的eureka地址即可,default
cluster的记录可以保留,如果有config service和admin service不是部署在SHAOY
和SHAJQ
这两个机房的,就会使用这条默认配置。
Key | Cluster | Value | Comment |
---|---|---|---|
eureka.service.url | default | <http://1.1.1.1:8080/eureka/> | 默认的Eureka服务Url |
eureka.service.url | SHAOY | <http://2.2.2.2:8080/eureka/> | SHAOY的Eureka服务Url |
eureka.service.url | SHAJQ | <http://3.3.3.3:8080/eureka/> | SHAJQ的Eureka服务Url |
2. namespace.lock.switch – 一次发布只能有一个人修改开关,用于发布审核
这是一个功能开关,如果配置为true的话,那么一次配置发布只能是一个人修改,另一个发布。
3. config-service.cache.enabled – 是否开启配置缓存
这是一个功能开关,如果配置为true的话,config service会缓存加载过的配置信息,从而加快后续配置获取性能。
默认为false,开启前请先评估总配置大小并调整config service内存配置。
4. item.key.length.limit – 配置项 key 最大长度限制
默认配置是128。
5. item.value.length.limit – 配置项 value 最大长度限制
默认配置是20000。
3. ConfigService && AdminService
可以通过两种方式获取安装包:
- 直接下载安装包
- 从GitHub Release页面下载预先打好的安装包
- 如果对Apollo的代码没有定制需求,建议使用这种方式,可以省去本地打包的过程
- 通过源码构建
– 从GitHub Release页面下载Source code包或直接clone源码后在本地构建
– 如果需要对Apollo的做定制开发,需要使用这种方式
获取apollo-configservice、apollo-adminservice、apollo-portal安装包
从GitHub Release页面下载最新版本的apollo-configservice-x.x.x-github.zip
、apollo-adminservice-x.x.x-github.zip
和apollo-portal-x.x.x-github.zip
即可。
同时启动 apollo-adminservice 和 apollo-configservice 项目,基于 apollo-assembly 项目来启动**。
这里主要是用源码构建
Apollo服务端需要知道如何连接到你前面创建的数据库,所以需要编辑scripts/build.sh,修改ApolloPortalDB和ApolloConfigDB相关的数据库连接串信息。
注意:填入的用户需要具备对ApolloPortalDB和ApolloConfigDB数据的读写权限。
#apollo config db info
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?useSSL=false&characterEncoding=utf8
apollo_config_db_username=用户名
apollo_config_db_password=密码(如果没有密码,留空即可)
# apollo portal db info
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?useSSL=false&characterEncoding=utf8
apollo_portal_db_username=用户名
apollo_portal_db_password=密码(如果没有密码,留空即可)
注1:由于ApolloConfigDB在每个环境都有部署,所以对不同的环境config-service和admin-service需要使用不同的数据库参数打不同的包,portal只需要打一次包即可
注2:如果不想config-service和admin-service每个环境打一个包的话,也可以通过运行时传入数据库连接串信息实现,具体可以参考 Issue 869
注3:每个环境都需要独立部署一套config-service、admin-service和ApolloConfigDB
配置各环境meta service地址
Apollo Portal需要在不同的环境访问不同的meta service(apollo-configservice)地址,所以需要在打包时提供这些信息。
假设DEV的apollo-configservice未绑定域名,地址是1.1.1.1:8080,FAT的apollo-configservice绑定了域名apollo.fat.xxx.com,UAT的apollo-configservice绑定了域名apollo.uat.xxx.com,PRO的apollo-configservice绑定了域名apollo.xxx.com,那么编辑scripts/build.sh,如下修改各环境meta service服务地址,格式为${env}_meta=http://${config-service-url:port}
,如果某个环境不需要,也可以直接删除对应的配置项:
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
META_SERVERS_OPTS="-Ddev_meta=$dev_meta -Dfat_meta=$fat_meta -Duat_meta=$uat_meta -Dpro_meta=$pro_meta"
注1: 为了实现meta service的高可用,推荐通过SLB(Software Load Balancer)做动态负载均衡
注2: meta service地址也可以填入IP,0.11.0版本之前只支持填入一个IP。从0.11.0版本开始支持填入以逗号分隔的多个地址(PR #1214),如
http://1.1.1.1:8080,http://2.2.2.2:8080
,不过生产环境还是建议使用域名(走slb),因为机器扩容、缩容等都可能导致IP列表的变化。
执行编译、打包
做完上述配置后,就可以执行编译和打包了。
注:初次编译会从Maven中央仓库下载不少依赖,如果网络情况不佳时很容易出错,建议使用国内的Maven仓库源,比如阿里云Maven镜像
./build.sh
该脚本会依次打包apollo-configservice, apollo-adminservice, apollo-portal。
注:由于ApolloConfigDB在每个环境都有部署,所以对不同环境的config-service和admin-service需要使用不同的数据库连接信息打不同的包,portal只需要打一次包即可
获取apollo-configservice安装包
位于apollo-configservice/target/
目录下的apollo-configservice-x.x.x-github.zip
需要注意的是由于ApolloConfigDB在每个环境都有部署,所以对不同环境的config-service需要使用不同的数据库参数打不同的包后分别部署
获取apollo-adminservice安装包
位于apollo-adminservice/target/
目录下的apollo-adminservice-x.x.x-github.zip
需要注意的是由于ApolloConfigDB在每个环境都有部署,所以对不同环境的admin-service需要使用不同的数据库参数打不同的包后分别部署
获取apollo-portal安装包
位于apollo-portal/target/
目录下的apollo-portal-x.x.x-github.zip
3.1. Apollo Config Service和Apollo Admin Service
我们在本地开发时,一般会在IDE中同时启动apollo-configservice
和apollo-adminservice
。
下面以Intellij Community 2016.2版本为例来说明如何在本地启动apollo-configservice
和apollo-adminservice
。
3.1.1 新建运行配置
3.1.2 Main class配置
com.ctrip.framework.apollo.assembly.ApolloApplication
注:如果希望独立启动
apollo-configservice
和apollo-adminservice
,可以把Main Class分别换成com.ctrip.framework.apollo.configservice.ConfigServiceApplication
和com.ctrip.framework.apollo.adminservice.AdminServiceApplication
3.1.3 VM options配置
-Dapollo_profile=github
-Dspring.datasource.url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8
-Dspring.datasource.username=root
-Dspring.datasource.password=
注1:spring.datasource相关配置替换成你自己的数据库连接信息,注意数据库是
ApolloConfigDB
注2:程序默认日志输出为/opt/logs/100003171/apollo-assembly.log,如果需要修改日志文件路径,可以增加
logging.file
参数,如下:-Dlogging.file=/your-path/apollo-assembly.log
3.1.4 Program arguments配置
--configservice --adminservice
3.1.5 运行
对新建的运行配置点击Run或Debug皆可。
启动完后,打开http://localhost:8080可以看到apollo-configservice
和apollo-adminservice
都已经启动完成并注册到Eureka。
3.2 Apollo-Portal
下面以Intellij Community 2016.2版本为例来说明如何在本地启动apollo-portal
。
2.2.1 新建运行配置
2.2.2 Main class配置
com.ctrip.framework.apollo.portal.PortalApplication
2.2.3 VM options配置
-Dapollo_profile=github,auth
-Ddev_meta=http://localhost:8080/
-Dserver.port=8070
-Dspring.datasource.url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
-Dspring.datasource.username=root
-Dspring.datasource.password=
注1:这里指定了apollo_profile是
github
和auth
,其中github
是Apollo必须的一个profile,用于数据库的配置,auth
是从0.9.0新增的,用来支持使用apollo提供的Spring Security简单认证,更多信息可以参考Portal-实现用户登录功能注2:spring.datasource相关配置替换成你自己的数据库连接信息,注意数据库是
ApolloPortalDB
。注3:默认ApolloPortalDB中导入的配置只会展示DEV环境的配置,所以这里配置了dev_meta属性,如果你希望在本地展示其它环境的配置,需要在这里增加其它环境的meta服务器地址,如fat_meta。
注4:这里指定了server.port=8070是因为
apollo-configservice
启动在8080端口,所以这里配置apollo-portal
启动在8070端口。注5:程序默认日志输出为/opt/logs/100003173/apollo-portal.log,如果需要修改日志文件路径,可以增加
logging.file
参数,如下:-Dlogging.file=/your-path/apollo-portal.log
2.2.4 运行
对新建的运行配置点击Run或Debug皆可。
启动完后,打开http://localhost:8070就可以看到Apollo配置中心界面了。
注:如果启用了
auth
profile的话,默认的用户名是apollo,密码是admin
2.2.5 Demo应用接入
为了更好的开发和调试,一般我们都会自己创建一个demo项目给自己使用。
可以参考应用接入指南中的一、普通应用接入指南创建自己的demo项目。
2.3 Java样例客户端启动
项目中有一个样例客户端的项目:apollo-demo
,下面以Intellij Community 2016.2版本为例来说明如何在本地启动。
2.3.1 配置项目AppId
在2.2.5 Demo应用接入
中创建Demo项目时,系统会要求填入一个全局唯一的AppId,我们需要把这个AppId配置到apollo-demo
项目的app.properties文件中:apollo-demo/src/main/resources/META-INF/app.properties
。
如我们自己的demo项目使用的AppId是100004458,那么文件内容就是:
app.id=100004458
注:AppId是应用的唯一身份标识,Apollo客户端使用这个标识来获取应用自己的私有Namespace配置。
对于公共Namespace的配置,没有AppId也可以获取到配置,但是就失去了应用覆盖公共Namespace配置的能力。
更多配置AppId的方式可以参考1.2.1 AppId
2.3.2 新建运行配置
2.3.3 Main class配置
SimpleApolloConfigDemo
2.3.4 VM options配置
-Dapollo.meta=http://localhost:8080
注:这里当前环境的meta server地址为
http://localhost:8080
,也就是apollo-configservice
的地址。更多配置Apollo Meta Server的方式可以参考1.2.2 Apollo Meta Server
2.3.5 概览
2.3.6 运行
对新建的运行配置点击Run或Debug皆可。
启动完后,忽略前面的调试信息,可以看到如下提示:
Apollo Config Demo. Please input key to get the value. Input quit to exit.
>
输入你之前在Portal上配置的值,如我们的Demo项目中配置了timeout
,会看到如下信息:
> timeout
> [SimpleApolloConfigDemo] Loading key : timeout with value: 100
客户端日志级别默认是
DEBUG
,如果需要调整,可以通过修改apollo-demo/src/main/resources/log4j2.xml
中的level配置
#