前言
在springCloud中有一个重要的组件就是配置中心,config:server,用于配置springboot中需要注入的各种配置项。但是现在发现越来越多的企业使用Apollo进行集成。博主在开发中也是使用Apollo进行配置。本文总结Apollo的的使用,集成到springboot,和注入方式等。
一、Apollo简介
Apollo是携程框架部门研发的开源配置管理中心,能够集中管理应用在不同环境、不同集群的配置,配置修改后能够实时的推送到应用端,并且有关于权限管理、流程治理等功能。
(一)Apollo支持四个维度管理key-value格式的配置
- application(应用级别的,针对于当前应用)
- environment(环境级别的,在不同环境下可以有不同的配置。比如dev、prod环境)
- cluster(集群。可以根据集群分为不同的配置)
- namespace(命名空间。不同的配置文件,比如db的配置,rpc的配置等等)
(二)Apollo的特性
- 可以统一去管理不同环境、不同集群的配置。
(1)同一份代码部署在不同的集群,可以有不同的配置。
(2)可以通过配置namespace去让不同的应用共享同一份配置(public公共配置),也可以通过关联公共的namespace,并且根据自己的需求对公共配置进行覆盖。(相当于子类可以继承父类,对于父类中的成员,不满足需要的可以自己进行覆盖。) - 支持热发布。在管理界面修改完配置后,客户端可以实时的接收到。(据它的描述,时间为1s)
- 每一次改动配置进行发布,都会有对应的版本的概念,方便后续进行回滚。
- 灰度发布。(是指改动配置点击发布,只针对部分实例生效。待观察之后,没有问题,再推送到所有实例。)
- 权限管理(可以针对不同的操作,分配以不同的权限。并且在配置的改动发布上,分为编辑和发布两个独立的操作。)
- 支持Java和.Net客户端。
- 提供开放平台API。
- 部署简单方便(目前唯一的外部依赖是MySQL,因此安装好JDK和MySQL就可以运行。)
二、Apollo的架构与工作原理
(一)Apollo的核心概念
- application(应用):实际使用配置的应用。
- environment(环境):配置所对应的环境。比如dev、prd等环境,在不同的环境中可以有不同的配置。默认是读取机器上的配置(server.properties中的env属性)
- cluster(集群):一个应用下不同实例的分组。比如将北京机房的应用实例分为一个集群,燕郊机房的应用实例分为另一个集群。同一个配置在不同的集群下可以有不同的值。默认是读取机器上(server.properties中的idc属性)
- namespace(命名空间):一个应用下不同配置的分组,可以理解为配置文件。比如数据库配置文件,rpc配置文件,以及应用自身的配置文件。
(二)Apollo客户端的实现原理
- 客户端和服务端通过http long polling保持了一个长连接,从而能第一时间获取配置更新的推送。
- 客户端会定时从Apollo配置中心服务端拉取应用的最新配置
- 客户端获取到最新的配置后,会保存在内存中。
- 客户端会将获取到的配置缓存一份在本地(为了保证服务不可用时,从本地恢复)
- 应用程序可以通过客户端取获取最新的配置。
- 注:想深入了解的可以去研究下源码,在github上同时也给出了Apollo的源码分析链接)
三、Apollo的安装(这里介绍通过docker进行安装)
1、 准备工作
Apllo的部署需要Mysql数据库,需要5.6.5以上版本。
2、 创建数据库
Apollo服务端共需要两个数据库:ApolloPortalDB和ApolloConfigDB,我们把数据库、表的创建和样例数据都分别准备了sql文件,只需要导入数据库即可。
执行两个sql文件(通过携程Apollo社区下载)
sql/apolloportaldb.sql
sql/apolloconfigdb.sql
会创建两个数据库
sql文件可在官网:Quick Start · apolloconfig/apollo Wiki · GitHub 下载
3、服务器上创建shell脚本文件
在/home/docker/script路径下创建“apollo”文件夹
在/home/docker/script/apollo路径下创建“apollo-portal.sh”脚本文件,内容为:
docker run -d \
--name apollo-portal \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL=
"jdbc:mysql://数据库地址/apollo_portal?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=数据库账号\
-e SPRING_DATASOURCE_PASSWORD=数据库密码\
-e APOLLO_PORTAL_ENVS=test \
-e TEST_META=http://服务器ip地址:8080 \
apolloconfig/apollo-portal
在/home/docker/script/apollo路径下创建“apollo-config.sh”脚本文件,内容为:
docker run -d \
--name apollo-configservice \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL=
"jdbc:mysql://数据库地址/apollo_config?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=数据库账号\
-e SPRING_DATASOURCE_PASSWORD=数据库密码\
apolloconfig/apollo-configservice
在/home/docker/script/apollo路径下创建“apollo-admin.sh”脚本文件,内容为:
docker run -d \
--name apollo-adminservice \
--net=host \
-v /tmp/logs:/opt/logs \
-e SPRING_DATASOURCE_URL=
"jdbc:mysql://数据库地址/apollo_config?characterEncoding=utf8" \
-e SPRING_DATASOURCE_USERNAME=数据库账号\
-e SPRING_DATASOURCE_PASSWORD=数据库密码\
apolloconfig/apollo-adminservice
4、通过docker拉取Apollo镜像
docker pull apolloconfig/apollo-configservice:latest
docker pull apolloconfig/apollo-adminservice:latest
docker pull apolloconfig/apollo-portal:latest
5、运行Apollo
1. ./apollo-portal.sh
2. ./apollo-config.sh
3. ./apollo-admin.sh
6.访问Apollo
访问服务器IP:8070可以进行访问,默认的用户名是apollo,密码是admin。
四、Apollo集成到springboot
1、引入maven
<!-- apollo -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>${apollo.version}</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-core</artifactId>
<version>${apollo.version}</version>
</dependency>
2.启动类注解@EnableApolloConfig
在Apollo系统配置完成配置后
注入方式一:
例子:
/**
* 微信主体appId
*/
@Value("${weixin.appid:-1}")
private String appid;
注入方式二:
使用注解@ConfigurationProperties 使用实体的方式,个人觉得这种方式更好。
例子:
Apollo中配置的格式和yml的格式一致
oss:
tencent:
domain:
region: mhyr-api
bucketName: mhyr-13015545476
secretId:
secretKey:
styleRule:
thumbnailStyleRule: "!Photo_Compression"
fileTypes: ## 允许上传的文件类型
- png
- jpg
- jpeg
- gif
- bmp
- svg
代码通过实体类类进行映射
@ConfigurationProperties(prefix = "oss.tencent")
public class TencentProperties {
/**域名*/
private String domain;
/**地域节点*/
private String region;
/**存储桶名称*/
private String bucketName;
/**secretId*/
private String secretId;
/**secretKey*/
private String secretKey;
/**图片策略*/
private String styleRule;
/**缩略图策略*/
private String thumbnailStyleRule;
/**文件类型*/
private List<String> fileTypes;
}