背景
- 在微服务发布部署过程中,子服务的数目很多,服务需要进行集群。服务配置使用配置文件存储,那样每次配置信息的修改,服务需要重新发布部署,非常繁琐。
- 分布式配置中心:微服务中较常变化的配置,放到分布式配置中心。当配置修改,分布式配置中心会将修改的配置推送给服务,服务就能实现配置的实时修改生效,服务不需要重新发布部署。
- Apollo:SpringCloud 提供的分布式配置中心 Config,没有管理端,使用起来很不人性化。所以我们这里改为整合 Apollo,实际生产中 SpringCloud 也一般是整合 Apollo。
分布式配置中心
分布式配置中心的组成
- 分布式配置信息持久化存储化仓库。常用的有:mysql、git。
- 分布式配置管理端。管理配置信息,进行信息的添加、编辑和修改。
- ConfigServer:保存最新配置信息。
- Client:需要拉取使用分布式配置的服务,我们就称为 Client。Client 需要整合 Apollo 的 Client 包,实现接收推送的配置信息或拉取配置信息的功能。
分布式配置中心的原理
- 配置管理:通过管理端,对仓库中配置信息进行操作。
- 配置消息推送:当持久化仓库中存储的配置有变更,通过消息推送机制,将修改的配置推送给 ConfigServer,ConfigServer 中始终保存着最新的配置信息。
- Client 获得 ConfigServer 中修改的配置。Client 获得变更配置的常用方案:2 种
- Client 能够与 ConfigServer 保持长连接,ConfigServer 将变更的配置实时推送给 Client。
- Client 定时拉取 ConfigServer 中的最新配置。
Apollo
Apollo 分布式配置中心,功能强大的一个中间件
- 它是一个功能强大的中间件。
- 它提供 4 种维度管理配置:application、environment、cluster、naspace。
- 支持发布审核:配置修改,不会生效;需要点击发布,修改的配置才会生效,推送给服务。
- 配置实时生效:配置修改,1s 以内都会推送到服务。
- 它提供配置操作的版本管理,支持回退版本。
- 权限管理:配置很重要,只有少数人有权限操作。
- 提供 RestfulApi:方便其他平台获取配置信息,方便整合 Apollo。
Apollo 组成 7 个
- 组成:ConfigService、AdminService、Client、Portal、MetaService、Eureka 和 MySQL
- ConfigService
- 提供功能:配置的主动拉取、推送等功能。
- 服务对象:Client。
- AdminService
- 提供的功能:提供配置的修改、发布等功能。AdminService 发布消息时,会通知 ConfigService。
- 服务对象:Portal。
- Client
- 提供的功能:定时拉取配置和接收配置修改通知等功能。SpringCloud 需要整合此,与 ConfigService 长连接,从而实现实时更新配置信息。
- 与 ConfigService 连接。Client 先要从 MetaService 获取 ConfigService 服务列表,根据负载均衡算法,选择一个 ConfigService 服务通讯。
- Portal
- 提供的功能:Apollo 的前端管理端,可以进行项目创建,配置修改,发布等功能。
- 调用 AdminService 服务接口,修改配置和发布通知。Portal 先要从 MetaService 获取 AdminService 服务列表,根据负载均衡算法,选择一个 AdminService 服务进行通信。
- Eureka
- 提供的功能:作为注册中心,提供服务注册和服务发现的功能。ConfigService 和 AdminService 要注册到 Eureka。
- Eureka 实际整合在 ConfigService 中。
- MetaService
- 提供的功能:对外提供服务发现接口,给其他平台调用。获得 ConfigService 和 AdminService 服务信息列表;这样 Client 和 Portal 不需要注册到 Eureka,也能获取到服务信息列表。
- MetaService 也注册到 Eureka,通过 DiscoveryClient 获取服务信息列表。
- MetaService 实际一般整合在 ConfigService 中,他们在同一个 JVM 中运行。Portal 通过连接 ConfigService 中 MetaService 获取 AdminService 服务列表信息。
- MySQL
Apollo 实现原理
- ConfigService 和 Client 保持长连接。
- 采用 Http Long Polling 技术实现长连接。
- 因为有长连接,所以才能实现 ConfigService 向 Client 推送配置更新通知,Client 将服务中配置修改为最新的。
- Client 默认拉取频率:5 分钟。由于网络抖动,可能配置修改通知没有通知到 Client,Client 定时拉取最新配置,保障配置最终是一致的。
- Client 为了保证高可用,会将每次拉取的数据在本地保存一份。当 Client 和 Config 断开连接,Client 可以使用本地的缓存文件中的配置。
- ConfigService 默认会与 Client 保持 60s 的长连接。
- 当 60s 内有配置更新,ConfigService 会通知客户端,将有配置变化的 namespace 告知 Client,Client 根据 namespace 拉取最新配置。
- 当 60s 内没有配置更新,ConfigService 会给 Client 发送一个 304 状态码的消息给 Client,然后连接中断。
- Client 只要接收到服务端的请求(不管是通知拉取配置的请求还是报错请求),都会重新建立长连接。
- 配置信息发布和拉取
- 配置信息发布:Portal 操作配置信息并发布后,ConfigService 会收到消息通知,更新配置,并将变更的配置推送给 Client。
- 配置拉取:为了防止网络抖动,导致 Client 配置信息不是最新的问题,Client 会通过定时拉取 ConfigService 的配置,保证配置最终是一致的。
Apollo 平台搭建
- Apollo 目前仅支持 Linux 系统部署。
- 我们这里选择 CentOS7 搭建 Apollo 平台
下载搭建 Apollo 所需的压缩包
- 包含三个压缩包:apollo-adminservice-1.6.1-github、apollo-configservice-1.6.1-github、apollo-portal-1.6.1-github。
- 将三个包放到目录: /thor/lib/apollo/ 下。
创建库表
- 部署 MySQL。这一步可以自己上网搜索怎么在 CentOS7 部署 MySQL。
- 创建库表
- 执行脚本:apolloconfigdb.sql。该数据库存储我们的配置信息。
- 执行脚本:apolloportaldb.sql。该数据库存储 Portal web 管理需要的门户信息。
解压三个包到特定目录
mkdir -p /thor/lib/apollo/apollo-adminservice-1.6.1-github
mkdir -p /thor/lib/apollo/apollo-configservice-1.6.1-github
mkdir -p /thor/lib/apollo/apollo-portal-1.6.1-github
unzip -o apollo-adminservice-1.6.1-github.zip -d /thor/lib/apollo/apollo-adminservice-1.6.1-github
unzip -o apollo-configservice-1.6.1-github.zip -d /thor/lib/apollo/apollo-configservice-1.6.1-github
unzip -o apollo-portal-1.6.1-github.zip -d /thor/lib/apollo/apollo-portal-1.6.1-github
部署 ConfigService
- 根据不同环境,可以部署多套。这里仅部署一套,方便入门。
- ConfigService 服务中包含:ConfigService、MetaService 和 Eureka。
- 修改 apollo-configservice 启动配置
# 进入配置文件
cd /thor/lib/apollo/apollo-configservice-1.6.1-github/config
vi application-github.properties
# 修改配置文件中数据库配置信息
spring.datasource.url = jdbc:mysql://ip:port/ApolloConfigDB?useSSL=false characterEncoding=utf8
spring.datasource.username = user
spring.datasource.password = password
- 启动服务
/thor/lib/apollo/apollo-configservice-1.6.1-github/scripts/startup.sh
- 默认端口:8080
部署 apollo-adminservice
- 根据不同环境,可以部署多套。这里仅部署一套即可,方便入门。
- 修改 apollo-adminservice 启动配置
# 进入配置文件
cd /thor/lib/apollo/apollo-adminservice-1.6.1-github/config
vi application-github.properties
# 修改配置文件中数据库配置信息
spring.datasource.url = jdbc:mysql://ip:port/ApolloConfigDB?useSSL=false&characterEncoding=utf8
spring.datasource.username = user
spring.datasource.password = password
- 启动服务
/thor/lib/apollo/apollo-adminservice-1.6.1-github/scripts/startup.sh
- 默认端口:8090
部署 apollo-portal
- 只需要部署一套即可。
- 修改 apollo-portal 启动配置。
# 进入配置文件
cd /thor/lib/apollo/apollo-portal-1.6.1-github/config
vi application-github.properties
# 修改配置文件中数据库配置信息
spring.datasource.url = jdbc:mysql://ip:port/ApolloPortalDB?useSSL=false characterEncoding=utf8
spring.datasource.username = user
spring.datasource.password = password
- 配置 portal 连接多套 configservice 和 adminservice。portal 需要同 configservice 的 metaservice 获取 adminService 服务列表信息,再跟 adminService 通信,所以 portal 设置 configservice 连接信息即可。
# 进入配置文件
cd /thor/lib/apollo/apollo-portal-1.6.1-github/config
vi apollo-env.properties
# 修改默认配置
local.meta=http://localhost:8080
dev.meta=http://localhost:8080
fat.meta=${fat_meta}
uat.meta=${uat_meta}
pro.meta=${pro_meta}
- 启动服务
/thor/lib/apollo/apollo-portal-1.6.1-github/scripts/startup.sh
- 默认端口:8070
- 默认用户/密码:apollo/admin
整合 Apollo
创建项目应用
- 在 Apollo Portal 管理端里创建项目,专门用于配置对应服务的配置。
- 我们这里为 apollo-demo 服务创建 test_1 项目
client 打包
- client 需要通过源码打包到我们本地仓库,引用本地仓库中对应的 Maven 包,即可整合 client。
- 打包方式有 2 种
- 统一打包:进入源码的 scripts/ 目录下,点击 build.bat,即可将全部包都打到本地仓库。
- 单一打包:通过 idea maven 一个个包的打。
Maven 依赖
application.yml 配置
app:
### portal 中新建 Application 的 AppId
id: test_1
apollo:
### configserver 的地址
meta: http://{configserver.host}:8080
启动类添加注解
- 开启 Client 框架功能
@EnableApolloConfig
配置类获取配置
控制层提供接口获取配置
GitHub 项目 demo