一、Apollo简介
Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。
Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。
二、Apollo特性
-
统一管理不同环境、不同集群的配置
- Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
- 同一份代码部署在不同的集群,可以有不同的配置,比如zookeeper的地址等。
- 通过命名空间(namespace)可以很方便地支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖。
-
配置修改实时生效(热发布)
- 用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序
-
版本发布管理
- 所有的配置发布都有版本概念,从而可以方便地支持配置的回滚
-
灰度发布
- 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例
-
权限管理、发布审核、操作审计
- 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
- 所有的操作都有审计日志,可以方便地追踪问题
-
客户端配置信息监控
- 可以在界面上方便地看到配置在被哪些实例使用
-
提供Java和.Net原生客户端
- 提供了Java和.Net的原生客户端,方便应用集成
- 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
- 同时提供了Http接口,非Java和.Net应用也可以方便地使用
-
提供开放平台API
- Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过Apollo出于通用性考虑,不会对配置的修改做过多限制,只要符合基本的格式就能保存,不会针对不同的配置值进行针对性的校验,如数据库用户名、密码,Redis服务地址等
- 对于这类应用配置,Apollo支持应用方通过开放平台API在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
-
部署简单
- 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
- 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
- Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
三、工作流程
- 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送
- 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置
- 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
- 客户端会把从服务端获取到的配置在本地文件系统缓存一份
- 应用程序从Apollo客户端获取最新的配置、订阅配置更新通知
四、分布式部署
使用主机:
apollo-dev 10.81.0.100
apollo-fat 10.81.0.101
apollo-uat 10.81.0.102
mysql 10.81.0.103
1、传统部署
-
运行环境依赖
所有apollo主机执行
- Java:1.8+
$ yum -y install java-1.8.0-openjdk*
mysql主机执行
- MySQL:5.6.5+
$ sh /root/scripts/mysql_install.sh
-
创建数据库
获取创建数据库sql脚本apolloportaldb.sql,apolloconfigdb.sql。(更具需求修改建库库名)
$ mysql -u root -p -P63307 -e "source /root/apolloportaldb.sql;" $ mysql -u root -p -P63307 -e "source /root/apolloconfigdb.sql;" $ mysql -u root -p -P63307 -e "create user apollo_user@'%' identified by 'abc123456';" $ mysql -u root -p -P63307 -e "grant all on apolloportaldb.* to apollo_user@'%';" $ mysql -u root -p -P63307 -e "grant all on apolloconfigdb_dev.* to apollo_user@'%';" $ mysql -u root -p -P63307 -e "grant all on apolloconfigdb_fat.* to apollo_user@'%';" $ mysql -u root -p -P63307 -e "grant all on apolloconfigdb_uat.* to apollo_user@'%';" $ mysql -u root -p -P63307 -e "flush privileges;"
-
安装软件包
apollo-uat主机执行
$ cd /usr/local/src $ wget https://github.com/apolloconfig/apollo/releases/download/v1.5.0/apollo-adminservice-1.5.0-github.zip $ wget https://github.com/apolloconfig/apollo/releases/download/v1.5.0/apollo-configservice-1.5.0-github.zip $ wget https://github.com/apolloconfig/apollo/releases/download/v1.5.0/apollo-portal-1.5.0-github.zip $ mkdir /usr/local/apollo-adminservice-1.5.0 $ unzip -q apollo-adminservice-1.5.0-github.zip -d /usr/local/apollo-adminservice-1.5.0/ $ mkdir /usr/local/apollo-configservice-1.5.0 $ unzip -q apollo-configservice-1.5.0-github.zip -d /usr/local/apollo-configservice-1.5.0/ $ mkdir /usr/local/apollo-portal-1.5.0 $ unzip -q apollo-portal-1.5.0-github.zip -d /usr/local/apollo-portal-1.5.0/
apollo-dev、apollo-fat主机执行
$ cd /usr/local/src $ wget https://github.com/apolloconfig/apollo/releases/download/v1.5.0/apollo-adminservice-1.5.0-github.zip $ wget https://github.com/apolloconfig/apollo/releases/download/v1.5.0/apollo-configservice-1.5.0-github.zip $ mkdir /usr/local/apollo-adminservice-1.5.0 $ unzip -q apollo-adminservice-1.5.0-github.zip -d /usr/local/apollo-adminservice-1.5.0/ $ mkdir /usr/local/apollo-configservice-1.5.0 $ unzip -q apollo-configservice-1.5.0-github.zip -d /usr/local/apollo-configservice-1.5.0/
-
配置数据库连接信息
所有apollo主机执行
根据各主机部署的服务及对应的环境进行数据库连接配置
$ vim /usr/local/apollo-configservice-1.5.0/config/application-github.properties # DataSource spring.datasource.url = jdbc:mysql://10.81.0.103:63307/库名_环境?useSSL=false&characterEncoding=utf8 spring.datasource.username = apollo_user spring.datasource.password = abc123456 $ vim /usr/local/apollo-adminservice-1.5.0/config/application-github.properties # DataSource spring.datasource.url = jdbc:mysql://10.81.0.103:63307/库名_环境?useSSL=false&characterEncoding=utf8 spring.datasource.username = apollo_user spring.datasource.password = abc123456 $ vim /usr/local/apollo-portal-1.5.0/config/application-github.properties # DataSource spring.datasource.url = jdbc:mysql://10.81.0.103:63307/库名_环境?useSSL=false&characterEncoding=utf8 spring.datasource.username = apollo_user spring.datasource.password = abc123456
-
Portal添加环境列表
-
protaldb增加环境
apollo.portal.envs配置项统一存储在ApolloPortalDB.ServerConfig表中,默认值是dev,如果portal需要管理多个环境的话,以逗号分隔即可(大小写不敏感)。也可以通过
管理员工具 - 系统参数
页面进行配置,无特殊说明则修改完一分钟实时生效 -
配置apollo-portal的meta service信息
$ vim /usr/local/apollo-portal-1.5.0/config/apollo-env.properties dev.meta=http://dev-apollo.testing.com fat.meta=http://fat-apollo.testing.com uat.meta=http://uat-apollo.testing.com
-
-
修改启动参数
-
apollo-configservice
- 修改JVM参数,可以修改scripts/startup.sh的
JAVA_OPTS
部分 - 调整服务的日志输出路径,可以修改scripts/startup.sh和apollo-configservice.conf中的
LOG_DIR
- 调整服务的监听端口,可以修改scripts/startup.sh中的
SERVER_PORT
。另外apollo-configservice同时承担meta server职责,如果要修改端口,注意要同时ApolloConfigDB.ServerConfig表中的eureka.service.url
配置项以及apollo-portal和apollo-client中的使用到的meta server信息
- 修改JVM参数,可以修改scripts/startup.sh的
-
apollo-adminservice
- 修改JVM参数,可以修改scripts/startup.sh的
JAVA_OPTS
部分 - 调整服务的日志输出路径,可以修改scripts/startup.sh和apollo-adminservice.conf中的
LOG_DIR
- 调整服务的监听端口,可以修改scripts/startup.sh中的
SERVER_PORT
- 修改JVM参数,可以修改scripts/startup.sh的
-
apollo-portalservice
- 修改JVM参数,可以修改scripts/startup.sh的
JAVA_OPTS
部分 - 调整服务的日志输出路径,可以修改scripts/startup.sh和apollo-portal.conf中的
LOG_DIR
- 调整服务的监听端口,可以修改scripts/startup.sh中的
SERVER_PORT
- 修改JVM参数,可以修改scripts/startup.sh的
-
-
配置nginx反向代理
server { listen 80; server_name dev-apollo.testing.com; location / { proxy_pass http://10.81.0.100:8080; } } server { listen 80; server_name fat-apollo.testing.com; location / { proxy_pass http://10.81.0.101:8080; } } server { listen 80; server_name uat-apollo.testing.com; location / { proxy_pass http://10.81.0.102:8080; } } server { listen 80; server_name apollo-portal.testing.com; location / { proxy_pass http://10.81.0.102:8070; } }
-
启动服务
启动顺序:configservice-->adminservice-->portal
configservice内置了Eureka和Meta Server需要优先重启
$ /usr/local/apollo-configservice-1.5.0/scripts/startup.sh $ /usr/local/apollo-adminservice-1.5.0/scripts/startup.sh $ /usr/local/apollo-portal-1.5.0/scripts/startup.sh
-
访问web页面
apollo
2、Docker部署
提前部署好docker环境
-
拉启apollo容器将容器目录cp到主机
$ mkdir -p /data/docker/apollo-deploy/apollo-{config,admin,portal} $ cd /data/docker/apollo-deploy $ docker cp apollo-config:/apollo-configservice/scripts apollo-config/ $ docker cp apollo-config:/apollo-configservice/config apollo-config/ $ docker cp apollo-admin:/apollo-adminservice/scripts apollo-admin/ $ docker cp apollo-admin:/apollo-adminservice/config apollo-admin/ $ docker cp apollo-portal:/apollo-portal/scripts apollo-portal/ $ docker cp apollo-portal:/apollo-portal/config apollo-portal/
-
按照传统部署步骤修改本地配置、数据库配置及启动脚本
-
使用docker-compose文件启动服务
docker-compose.yml
version: '3' services: apollo-config: image: 'apolloconfig/apollo-configservice:1.9.2' container_name: 'apollo-config' dns: - 192.168.109.104 - 192.168.94.95 expose: - 8080 extra_hosts: - "dev-apollo.testing.com:192.168.87.194" - "uat-apollo.testing.com:192.168.87.194" ports: - "8080:8080" networks: - apollo volumes: - /opt/logs:/opt/logs - ./apollo-config/scripts:/apollo-configservice/scripts - ./apollo-config/config:/apollo-configservice/config environment: - LOG_FOLDER=/opt/logs/apolloconfig apollo-admin: image: 'apolloconfig/apollo-adminservice:1.9.2' container_name: 'apollo-admin' depends_on: - apollo-config dns: - 192.168.109.104 - 192.168.94.95 expose: - 8090 extra_hosts: - "dev-apollo.testing.com:192.168.87.194" - "uat-apollo.testing.com:192.168.87.194" ports: - "8090:8090" networks: - apollo volumes: - /opt/logs:/opt/logs - ./apollo-admin/scripts:/apollo-adminservice/scripts - ./apollo-admin/config:/apollo-adminservice/config environment: - LOG_FOLDER=/opt/logs/apolloadmin apollo-portal: image: 'apolloconfig/apollo-portal:1.9.2' container_name: 'apollo-portal' depends_on: - apollo-config - apollo-admin dns: - 192.168.109.104 - 192.168.94.95 expose: - 8070 extra_hosts: - "dev-apollo.testing.com:192.168.87.194" - "uat-apollo.testing.com:192.168.87.194" ports: - "8070:8070" networks: - apollo volumes: - /opt/logs:/opt/logs - ./apollo-portal/config:/apollo-portal/config - ./apollo-portal/scripts:/apollo-portal/scripts environment: - LOG_FOLDER=/opt/logs/apolloportal networks: apollo: name: apollo
$ cd /data/docker/apollo-deploy && docker-compose config #检查compose文件是否正确 $ docker-compose up -d
五、客户端使用
1、Java客户端使用
Spring Boot集成方式
-
通过Spring Boot的配置文件配置连接Apollo信息
#设置应用的身份信息 app.id=YOUR-APP-ID #设置连接meta server地址,meta server和config service是部署在同一个JVM进程,所以meta server的地址就是config service的地址 apollo.meta=http://config-service-url #设置连接集群 apollo.cluster=SomeCluster #自定义缓存路径 apollo.cacheDir=/opt/data/some-cache-dir #设置内存中的配置项是否保持和页面上的顺序一致 apollo.property.order.enable=true #注入多个namespace apollo.bootstrap.enabled = true apollo.bootstrap.namespaces = application,FX.apollo,application.yml
-
修改pom文件添加依赖
Apollo的客户端jar包已经上传到中央仓库,应用在实际使用时只需要按照如下方式引入即可
<dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>1.5.0</version> </dependency>
2、.NET客户端使用
-
DLL引用
在Nuget上引入Com.Ctrip.Framework.Apollo.Configuration的依赖
$ dotnet add package Com.Ctrip.Framework.Apollo --version 2.4.1 $ dotnet add package Com.Ctrip.Framework.Apollo.Configuration --version 2.4.1
-
appsettings.json中添加apollo配置
{ "apollo": { "AppId": "YOUR-APP-ID", "Cluster": "SomeCluster", "Env": "UAT", "LocalCacheDir": "/opt/data/some-cache-dir", "Meta": { "DEV": "http://dev-apollo.testing.com", "FAT": "http://fat-apollo.testing.com", "UAT": "http://uat-apollo.testing.com" }, "Namespaces": [ "some namespace", "application.json", "application" ] } }
-
修改Program.cs文件
.ConfigureAppConfiguration((hostingContext, builder) => { builder .AddApollo(builder.Build().GetSection("apollo")) .AddDefault() .AddNamespace("some namespace") .AddNamespace("application.json") .AddNamespace("application"); })
网友评论