Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。

详细可参考:https://github.com/ctripcorp/apollo/wiki

安装步骤

1、下载安装包 https://pan.baidu.com/s/1Ieelw6y3adECgktO0ea0Gg#list/path=%2F
2、解压,配置数据库连接地址 demo.sh

  1. # apollo config db info
  2. apollo_config_db_url=jdbc:mysql://localhost:3306/ApolloConfigDB?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  3. apollo_config_db_username=root
  4. apollo_config_db_password=root
  5. # apollo portal db info
  6. apollo_portal_db_url=jdbc:mysql://localhost:3306/ApolloPortalDB?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
  7. apollo_portal_db_username=root
  8. apollo_portal_db_password=root

3、配置数据库

  • 创建数据库 ApolloConfigDB、执行 SQL 脚本 apolloconfigdb.sql
  • 创建数据库 ApolloPortalDB、执行 SQL 脚本 apolloportaldb.sql

4、启动 demo.sh

  1. $ D:/Development/apollo-quick-start-1.6.1/demo.sh start
  2. Windows new JAVA_HOME is: /d/Development/Java/jdk1.8.0_231
  3. ==== starting service ====
  4. Service logging file is ./service/apollo-service.log
  5. Started [1564]
  6. Waiting for config service startup...........
  7. Config service started. You may visit http://localhost:8080 for service status now!
  8. Waiting for admin service startup..
  9. Admin service started
  10. ==== starting portal ====
  11. Portal logging file is ./portal/apollo-portal.log
  12. Started [1637]
  13. Waiting for portal startup.......
  14. Portal started. You can visit http://localhost:8070 now!

访问:http://127.0.0.1:8070/signin 进入管理控制台界面,默认用户为 apollo,密码为 admin
image.png

架构设计

Apollo 架构模块的概览

Apollo 默认启动了三个服务

  • 8070:管理控制台
  • 8080:Eurka
  • 8090:配置服务

image.png
上图简要描述了Apollo的总体设计,我们可以从下往上看:

  • Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端
  • Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)
  • Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳
  • 在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口
  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试
  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试
  • 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

服务端架构设计

image.png

  1. 用户在Portal操作配置发布
  2. Portal调用Admin Service的接口操作发布
  3. Admin Service发布配置后,发送ReleaseMessage给各个Config Service
  4. Config Service收到ReleaseMessage后,通知对应的客户端

客户端架构设计

image.png

  1. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)
  2. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。
    • 这是一个fallback机制,为了防止推送机制失效导致配置不更新
    • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
    • 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟。
  3. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
  4. 客户端会把从服务端获取到的配置在本地文件系统缓存一份
    • 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
  5. 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知

image.png

参数配置

Apollo 的相关参数配置,如:部门的添加、开发环境的添加,都是通过 key/value 的形式,往数据库的配置字段中添加的,库:apolloportaldb,表:serverconfig

我们可以通过 管理员工具 -> 系统参数 进行设置,也可以直接修改数据库

Java Client

依赖

  1. <!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
  2. <dependency>
  3. <groupId>com.ctrip.framework.apollo</groupId>
  4. <artifactId>apollo-client</artifactId>
  5. <version>1.7.0</version>
  6. </dependency>

配置

-Dapp.id=test -Dapollo.meta=http://localhost:8080 -Denv=DEV

代码

public class Test {

    public static void main(String[] args) {
        // 默认的 application namespace
        Config config = ConfigService.getAppConfig(); // config instance is singleton for each namespace and is never null
        String name = config.getProperty("name", null);
        System.out.println("name = " + name);

        // 我们自定义的 namespace
        Config test_namespace = ConfigService.getConfig("test_namespace");
        String username = test_namespace.getProperty("username", null);
        System.out.println("username = " + username);
    }

}

Spring Boot 整合

依赖

<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
<dependency>
  <groupId>com.ctrip.framework.apollo</groupId>
  <artifactId>apollo-client</artifactId>
  <version>1.7.0</version>
</dependency>

配置

app:
  id: TEST # apollo AppId
apollo:
  cluster: defalut # 集群名称
  meta: http://127.0.0.1:8080
  bootstrap:
    namesapces: application
    enable: true

image.png

代码

启动类上添加 @EnableApolloConfig 注解

@RestController
@RequestMapping("/test")
@SpringBootApplication
@EnableApolloConfig
public class ApolloBootClient {

    public static void main(String[] args) {
        SpringApplication.run(ApolloBootClient.class, args);
    }

    @Value("${timeout}")
    private long timeout;

    @Value("${salt}")
    private String salt;

    @RequestMapping("/load")
    public R load() {
        return R.success().set("timeout", timeout).set("salt", salt);
    }

}