随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址等等。
对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制等等。
在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。
Apollo 配置中心应运而生!Apollo - 一个可靠的配置管理系统。
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。服务端基于 Spring Boot 和 Spring Cloud 开发,打包后可以直接运行,不需要额外安装 Tomcat 等应用容器。
Apollo 支持 4 个维度管理 Key-Value 格式的配置:
同时,Apollo 基于开源模式开发,开源地址:https://github.com/ctripcorp/apollo
官网文档:https://github.com/ctripcorp/apollo/wiki/Quick-Start
演示环境(Demo):
上图是Apollo配置中心中一个项目的配置首页
官方文档:https://github.com/ctripcorp/apollo/wiki/Apollo配置中心设计
上图简要描述了 Apollo 的总体设计,我们可以从下往上看:
上图简要描述了配置发布的大致过程:
上图简要描述了Apollo客户端的实现原理:
apollo.refreshInterval
来覆盖,单位为分钟。点击链接观看:Apollo 搭建服务端视频(获取更多请关注公众号「哈喽沃德先生」)
由于需要同时启动服务端和客户端,所以建议安装Java 1.8+。
Apollo的表结构对timestamp
使用了多个default声明,所以需要5.6.5以上版本。
Apollo 给我们准备好了一个Quick Start安装包,大家只需要下载到本地,就可以直接使用,免去了编译、打包过程。
安装包共50M,如果访问github网速不给力的话,可以从百度网盘下载。
Apollo 服务端共需要两个数据库:ApolloPortalDB
和ApolloConfigDB
,我们把数据库、表的创建和样例数据都分别准备了 sql 文件,只需要导入数据库即可。
❝注意:如果你本地已经创建过Apollo数据库,请注意备份数据。我们准备的sql文件会清空Apollo相关的表。
❞
通过各种MySQL客户端导入sql/apolloportaldb.sql即可。
通过各种MySQL客户端导入sql/apolloconfigdb.sql即可。
Apollo 服务端需要知道如何连接到你前面创建的数据库,所以需要编辑demo.sh,修改 ApolloPortalDB 和 ApolloConfigDB 相关的数据库连接串信息。
❝注意:填入的用户需要具备对 ApolloPortalDB 和 ApolloConfigDB 数据的读写权限。
❞
#apollo config db info
apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=用户名
apollo_config_db_password=密码(如果没有密码,留空即可)
# apollo portal db info
apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=用户名
apollo_portal_db_password=密码(如果没有密码,留空即可)
❝注意:不要修改 demo.sh 的其它部分
❞
Quick Start脚本会在本地启动3个服务,分别使用8070, 8080, 8090端口,请确保这3个端口当前没有被使用。
.https://img.qb5200.com/download-x/demo.sh start
Apollo 提供的脚本文件为 .sh
文件,如果你的安装环境是在 Linux 系统下直接运行以上命令即可,如果你想在 Windows 环境下运行该脚本,先安装 Git 然后在 demo.sh
所在目录下鼠标右键点击 Git Bash Here
,然后再通过以上命令运行脚本即可。
当看到如下输出后,就说明启动成功了!
==== starting service ====
Service logging file is ./service/apollo-service.log
Started [10768]
Waiting for config service startup.......
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup....
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [10846]
Waiting for portal startup......
Portal started. You can visit http://localhost:8070 now!
如果启动遇到了异常,可以分别查看 service 和 portal 目录下的 log 文件排查问题。
❝注:在启动 apollo-configservice 的过程中会在日志中输出 eureka 注册失败的信息,如
❞com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused
。需要注意的是,这个是预期的情况,因为 apollo-configservice 需要向 Meta Server(它自己)注册服务,但是因为在启动过程中,自己还没起来,所以会报这个错。后面会进行重试的动作,所以等自己服务起来后就会注册正常了。
访问:http://localhost:8070/ Quick Start 集成了 Spring Security,输入用户名 apollo,密码 admin 后登录。
登录成功后,首页如下,Apollo 还提供了一个 SampleApp
样本案例供我们学习使用。
点击对应按钮创建项目。
这里先通过默认的样例部门演示(后面我会讲如何添加部门),AppId 对应客户端配置文件中 app.id。
创建成功如下图。
点击链接观看:Apollo 客户端接入服务端视频(获取更多请关注公众号「哈喽沃德先生」)
下面通过最常用、便捷的方式,即基于 Spring Boot 的集成方式来接入服务端。
apollo-demo
聚合工程。Spring Boot 2.2.4.RELEASE
order-service
:订单服务,端口 9090
order-service02
:订单服务,端口 9091
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.6.0</version>
<https://img.qb5200.com/download-x/dependency>
order-service
和 order-service02
的配置信息除端口外一致。
server:
port: 9090 # 端口
spring:
application:
name: order-service # 应用名称
# apollo 相关配置
app:
id: order-service # 与 Apollo 配置中心中的 AppId 一致
apollo:
meta: http://localhost:8080 # Apollo 中的 Eureka 注册中心地址
#cluster: # 指定 Apollo 集群,相同集群实例使用对应集群的配置
#cacheDir: # 配置缓存目录,网络不可用时任然可提供配置服务
bootstrap:
enable: true # 启用 apollo
env: DEV # 指定环境
# 自定义配置
name: order-service-dev
mysql:
host: localhost
port: 3306
username: root
password: root
order-service
和 order-service02
的配置文件实体类代码一致。
package com.example.config;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ConfigProperties {
@Value("${name}")
private String name;
@Value("${mysql.host}")
private String mysqlHost;
@Value("${mysql.port}")
private Integer mysqlPort;
@Value("${mysql.username}")
private String mysqlUsername;
@Value("${mysql.password}")
private String mysqlPassword;
}
order-service
和 order-service02
的控制层代码一致。
package com.example.controller;
import com.example.config.ConfigProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class ConfigController {
@Autowired
private ConfigProperties configProperties;
@Value("${name}")
private String name;
@GetMapping("/name")
public String getName() {
return configProperties.getName();
}
@GetMapping("/mysql")
public Map<Object, Object> getMySQLProperties() {
// JDK9中的新特性,快速创建只读集合。
return Map.of("host", configProperties.getMysqlHost(),
"port", configProperties.getMysqlPort(),
"username", configProperties.getMysqlUsername(),
"password", configProperties.getMysqlPassword());
}
}
启动类需要添加 @EnableApolloConfig
注解。
order-service
和 order-service02
的启动类代码一致。
package com.example;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableApolloConfig
@SpringBootApplication
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
访问:http://localhost:9090/name 和 http://localhost:9091/name 结果如下:
访问:http://localhost:9090/mysql 和 http://localhost:9091/mysql 结果如下:
进入项目后点击右上角的 新增配置
。
添加配置项 name
、mysql.username
、mysql.password
。
将刚才添加的配置信息批量发布至应用。
控制台打印信息如下:
c.f.a.s.p.AutoUpdateConfigChangeListener : Auto update apollo changed value successfully, new value: order-service-dev-2.0, key: name, beanName: configController, field: com.example.controller.ConfigController.name
c.f.a.s.p.AutoUpdateConfigChangeListener : Auto update apollo changed value successfully, new value: root123, key: mysql.password, beanName: configProperties, field: com.example.config.ConfigProperties.mysqlPassword
c.f.a.s.p.AutoUpdateConfigChangeListener : Auto update apollo changed value successfully, new value: root123, key: mysql.username, beanName: configProperties, field: com.example.config.ConfigProperties.mysqlUsername
访问:http://localhost:9090/name 和 http://localhost:9091/name 结果如下:
访问:http://localhost:9090/mysql 和 http://localhost:9091/mysql 结果如下:
❝以上只是 Apollo 的入门教程,后面我们会学习 Apollo 的更多高级玩法,比如多环境部署,高可用环境搭建等等。
下一篇我们讲解 Apollo 部门管理、用户管理、配置管理、集群管理,记得关注噢~
❞
本文采用 知识共享「署名-非商业性使用-禁止演绎 4.0 国际」许可协议
。
大家可以通过 分类
查看更多关于 Spring Cloud
的文章。