Apollo分布式配置中心

1.概述

1.1定义

Apollo,称阿波罗,是携程研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。它支持4个维度管理Key-Value格式的配置。

1.2特性

1)统一管理不同环境、不同集群的配置

Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。同一份代码部署在不同的集群,可以有不同的配置。通过命名空间(namespace)可以很方便的支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖

2)配置修改实时生效(热发布)

用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序

3)版本发布管理

所有的配置发布都有版本概念,从而可以方便地支持配置的回滚

4)灰度发布

点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例

5)权限管理、发布审核、操作审计

应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。另外所有的操作都有审计日志,可以方便的追踪问题

1.3执行流程

执行流程图如下:

流程说明:

A:用户在配置中心发布或修改配置

B:Apollo客户端定时拉取配置中心的配置。若配置中心发生故障,则apollo客户端会从本地缓存中获取配置信息

C:应用程序从客户端获取配置信息并更新通知

D:除了apollo客户端定时从拉取配置中心拉取之外,配置中心还可以实时的推送配置更新信息到apollo客户端,那么客户端再把配置给应用程序

2.安装及部署

可参考官方指南https://github.com/ctripcorp/apollo/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97#,本操作均按照指南进行说明的。

2.1环境要求

1)服务端基于Spring Boot框架,一般放在Centos7上

2)JDK版本需在1.8+

3)MySQL版本需在5.6.5+

2.2在Linux手动部署服务端

2.2.1创建数据库

Apollo服务端共需要两个数据库:ApolloPortalDBApolloConfigDB。ApolloPortalDB只需要在生产环境部署一个即可,而ApolloConfigDB需要在每个环境部署一套。

1)创建ApolloPortalDB数据库:复制apolloportaldb.sql后执行。

2)创建ApolloConfigDB数据库:复制apolloconfigdb.sql后执行。

2.2.2下载安装包

1)直接从GitHub Release下载即可。

这里以1.8.1版本为例,需要分别下载apollo-configservice-1.8.1-github.zip、apollo-adminservice-1.8.1-github.zip和apollo-portal-1.8.1-github.zip。如下图:

2)修改数据库配置信息 

下载后在本地解压,然后分别打开三个这文件夹下的config/application-github.properties文件,修改数据库的连接信息。下面以一个为例说明:

# DataSource
spring.datasource.url = jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8
spring.datasource.username = admin
spring.datasource.password = 1234

需要修改数据库的地址,用户名和密码。需要注意的是在用户名和密码未部不能有空格!这里的MySQL使用的是8.0+版本的,使用docker容器启动的,专门创建了一个用户,用于外部的访问。

3)修改portal的环境配置

这里以默认的dev环境进行说明,若需要添加其他的环境,可参考后续章节。

打开apollo-portal-1.8.1-github/config/apollo-env.properties文件,修改dev.meta的值

dev.meta=http://localhost:8080

 

2.2.3启动服务

1)把上一步修改好后的三个文件夹全部上传到虚拟机中。

2)部署apollo-configservice

cd apollo-configservice-1.8.1-github/scripts
./startup.sh

启动需要几分钟,看到下图的执行结果说明启动成功!后面的两个服务类同。

停止服务

./shutdown.sh

3)部署apollo-adminservice

cd apollo-adminservice-1.8.1-github/scripts 
./startup.sh

4)部署apollo-portal

cd apollo-portal-1.8.1-github/scripts 
./startup.sh

都启动后访问http://192.168.86.128:8070/,这里的ip是虚拟机的ip。看到apollo的登录页面,说明服务均部署成功。

5)登录管理页面

默认的用户名是apollo,密码是admin,即可登录进入首页,第一次进来可能会提示下图的错误信息,这时需要点击左下角的补缺环境就可以正常使用了。

正常情况下是下图:

 用户名和密码存储在apolloportaldb数据库的Users表中,可修改。

2.3在Linux使用Docker部署服务端

Apollo1.7.0及以上的版本才能使用Docker部署,这里以1.8.1版本为例。数据库在此略,请参考上一小节的创建数据库操作说明。

2.3.1部署apollo-configservice

1)拉取镜像

docker pull apolloconfig/apollo-configservice:1.8.1

2)启动镜像

首次启动时需要指定一些参数,后续只需要启动此容器即可。每行尾部的反斜杠“\”表示换行。

docker run -p 8080:8080 \
    -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8" \
    -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234 \
    -e EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128
    -d -v /tmp/logs:/opt/logs --name apollo-configservice apolloconfig/apollo-configservice:1.8.1

参数说明:

SPRING_DATASOURCE_URL: 环境ApolloConfigDB的数据库地址

SPRING_DATASOURCE_USERNAME: 环境ApolloConfigDB数据库用户名

SPRING_DATASOURCE_PASSWORD: 环境ApolloConfigDB数据库密码 
 
EUREKA_INSTANCE_IP_ADDRESS:eureka的地址,不能再使用localhost

由于mysql也使用的是docker容器,演示示例中客户端和服务端不在同一台机器上,故这里数据的连接必须使用ip进行访问,不能使用localhost,否则服务无法启动成功。若在正式环境中,服务端和客户端在同一机器上,那么就不需要设置eureka地址。后续使用docker部署同。

3)修改eureka的地址

由于使用的是容器,故需要把eureka的地址中localhost改为ip:

use ApolloConfigDB;
update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url'

这里不改的话,config服务启动时会报异常。

12.3.2部署apollo-adminservice

1)拉取镜像

docker pull apolloconfig/apollo-adminservice:1.8.1

2)启动镜像

首次启动时需要指定一些参数,后续只需要启动此容器即可。每行尾部的反斜杠“\”表示换行。

docker run -p 8090:8090 \
    -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8" \
    -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234 \
    -d -v /tmp/logs:/opt/logs --name apollo-adminservice apolloconfig/apollo-adminservice:1.8.1

参数说明:

SPRING_DATASOURCE_URL: 环境ApolloConfigDB的数据库地址

SPRING_DATASOURCE_USERNAME: 环境ApolloConfigDB数据库用户名

SPRING_DATASOURCE_PASSWORD: 环境ApolloConfigDB数据库密码  

2.3.3部署apollo-portal

1)拉取镜像

docker pull apolloconfig/apollo-portal:1.8.1

2)启动镜像

首次启动时需要指定一些参数,后续只需要启动此容器即可。每行尾部的反斜杠“\”表示换行。

docker run -p 8070:8070 \
    -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8" \
    -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234\
    -e APOLLO_PORTAL_ENVS=dev \
    -e DEV_META=http://192.168.86.128:8080 \
    -d -v /tmp/logs:/opt/logs --name apollo-portal apolloconfig/apollo-portal:1.8.1

参数说明:

SPRING_DATASOURCE_URL: 环境ApolloPortalDB数据库地址

SPRING_DATASOURCE_USERNAME: 环境ApolloPortalDB数据库用户名

SPRING_DATASOURCE_PASSWORD: 环境ApolloPortalDB数据库密码

APOLLO_PORTAL_ENVS(可选): 对应ApolloPortalDB中的apollo.portal.envs配置项,如果没有在数据库中配置的话,可以通过此环境参数配置

DEV_META/PRO_META(可选): 配置对应环境的Meta Service地址,以${ENV}_META命名,需要注意的是如果配置了ApolloPortalDB中的apollo.portal.meta.servers配置,则以apollo.portal.meta.servers中的配置为准

这里只配置了dev环境。若配置多环境,启动时再添加参数即可,下列代码标红的地方便是添加pro后的样子:

docker run -p 8070:8070 \
    -e SPRING_DATASOURCE_URL="jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8" \
    -e SPRING_DATASOURCE_USERNAME=admin -e SPRING_DATASOURCE_PASSWORD=1234\
    -e APOLLO_PORTAL_ENVS=dev,pro \
    -e DEV_META=http://localhost:8080 -e PRO_META=http://ip:8080 \
    -d -v /tmp/logs:/opt/logs --name apollo-portal apolloconfig/apollo-portal:1.8.1

2.4在Linux使用Docker-Compose部署服务端

在上一小节使用的docker命令方式部署服务端,本小节使用Docker-Compose进行部署,故默认已安装docker-compose镜像,若未安装,请参考https://www.cnblogs.com/zys2019/p/13292619.html#_label4

1)数据库请参数2.2小节的创建数据库操作。

2)修改数据库中eureka的地址

use ApolloConfigDB;
update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url'

3)在opt目录下新建apollo目录,在apollo目录新建.env文件,内容如下:

DATASOURCE_URL_CONFIG=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB?characterEncoding=utf8
DATASOURCE_URL_PORTAL=jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8
DATASOURCE_USERNAME=admin
DATASOURCE_PASSWORD=1234
APOLLO_PORTAL_ENVS=dev
DEV_META=http://192.168.86.128:8080
EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128

此文件的作用是定义公共的变量,在docker-compose.yml中直接获取即可。

4)在apollo目录下新建docker-compose.yml文件,内容如下:

version: '3.7'
services:
  apollo-configservice:
    container_name: apollo-configservice
    restart: always
    image: apolloconfig/apollo-configservice:1.8.1
    ports:
      - 8080:8080
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS}
    volumes:
      - /tmp/logs:/opt/logs

  apollo-adminservice:
    container_name: apollo-adminservice
    depends_on:
      - apollo-configservice
    restart: always
    image: apolloconfig/apollo-adminservice:1.8.1
    expose:
      - '8090'
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
    volumes:
      - /tmp/logs:/opt/logs

  apollo-portal:
    container_name: apollo-portal
    depends_on:
      - apollo-adminservice
    restart: always
    image: apolloconfig/apollo-portal:1.8.1
    ports:
      - 8070:8070
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PORTAL}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      APOLLO_PORTAL_ENVS: ${APOLLO_PORTAL_ENVS}
      DEV_META: ${DEV_META}
    volumes:
      - /tmp/logs:/opt/logs

完成后在当前位置启动docker-compose即可,命令是:

docker-compose up -d

2.5在配置中心配置相关信息

服务端部署完成后,访问http://192.168.86.128:8070并登录进入首页。下面的操作均以进入首页后说明。

1)创建项目

点击首页的创建项目,填写项目的相关信息

部门:选择应用所在的部门

应用AppId:用来标识应用身份的唯一id,格式为string

应用名称:应用名,仅用于界面展示。

应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限。

2)添加配置项

点击页面的新增配置按钮,配置需要管理的 application.properties 中的属性,这是第一步。

在弹框中输入key和value,这里以count=20为例,点击提交

提交后在页面会显示出来

3)发布配置

 选择发布按钮,发布配置,这是第二步。在发布的弹框中选择发布按钮即可

发布后界面就会显示已发布

3.apollo客户端的安装

经过配置中心的配置,就可以使用SpringBoot来整合apollo了。源码:https://github.com/zhongyushi-git/springboot-apollo-demo.git

1)新建一个SpringBoot的项目。新建时选择web的依赖

2)导入apollo的依赖

        <dependency>
            <groupId>com.ctrip.framework.apollo</groupId>
            <artifactId>apollo-client</artifactId>
            <version>1.3.0</version>
        </dependency>

3)在配置文件application.properties配置apollo的相关信息

#阿波罗配置
app.id = apollo-application
apollo.meta=http://192.168.86.128:8080
apollo.bootstrap.enabled = true
apollo.bootstrap.eagerLoad.enabled=true

说明:

app.id:AppId是应用的身份信息,是配置中心获取配置的一个重要信息。这个必须和配置中心保持一致

apollo.meta:指定config服务地址

apollo.bootstrap.enabled:在应用启动阶段,向Spring容器注入被托管的application.properties文件的配置信息。

apollo.bootstrap.eagerLoad.enabled:将Apollo配置加载提到初始化日志系统之前。

4)在启动类上添加注解@EnableApolloConfig

5)编写一个controller接口,读取配置文件的信息

package com.zxh.springbootapollodemo.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {

    @Value("${count}")
    private Integer count;

    @GetMapping("/get")
    public String test() {
        return "count的值:" + count;
    }
}

6)启动项目,访问http://localhost:8080/test/get,返回正确的信息

7)在配置中心修改count的值,将其改为666并发布

8)看到控制台打印了日志,更新了配置的信息,再访问get接口,返回的也是最新的值

当然有时无法及时的更新,可能是网络原因,也可能是时间问题,发布后等待一分钟再进行测试。

4.使用Docker-Compose部署多环境

上述讲的都是单个环境,一般情况下会部署多环境,下面在同一台linux机器上部署dev和pro环境。

4.1创建数据库

参考2.2小节的创建数据库操作,分别创建如下图数据库:

 其中ApolloPortalDB只需要创建一个,而ApolloConfigDB需要对每个环境单独创建一个。创建完成后修改eureka的服务地址:

use ApolloConfigDB_DEV;
update ServerConfig t set t.Value = 'http://192.168.86.128:8080/eureka/' where t.Key = 'eureka.service.url';

use ApolloConfigDB_PRO;
update ServerConfig t set t.Value = 'http://192.168.86.128:8081/eureka/' where t.Key = 'eureka.service.url';

4.2创建.env文件

在/opt目录下新建目录,名字为apollo_profile,在apollo_profile目录下新建.env文件,内容如下:

DATASOURCE_URL_CONFIG_DEV=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB_DEV?characterEncoding=utf8
DATASOURCE_URL_CONFIG_PRO=jdbc:mysql://192.168.86.128:3306/ApolloConfigDB_PRO?characterEncoding=utf8
DATASOURCE_URL_PORTAL=jdbc:mysql://192.168.86.128:3306/ApolloPortalDB?characterEncoding=utf8
DATASOURCE_USERNAME=admin
DATASOURCE_PASSWORD=1234
APOLLO_PORTAL_ENVS=dev,pro
DEV_META=http://192.168.86.128:8080
PRO_META=http://192.168.86.128:8081
EUREKA_INSTANCE_IP_ADDRESS=192.168.86.128

这里面设置了一些公共的变量,方便维护。

4.3创建docker-compose.yml文件

在apollo_profile目录下新建docker-compose.yml文件,内容如下:

version: '3.7'
services:
  apollo-configservice-dev:
    container_name: apollo-configservice-dev
    restart: always
    image: apolloconfig/apollo-configservice:1.8.1
    ports:
      - 8080:8080
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_DEV}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS}
    volumes:
      - /tmp/logs:/opt/logs

  apollo-adminservice-dev:
    container_name: apollo-adminservice-dev
    depends_on:
      - apollo-configservice-dev
    restart: always
    image: apolloconfig/apollo-adminservice:1.8.1
    expose:
      - '8090'
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_DEV}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
    volumes:
      - /tmp/logs:/opt/logs

  apollo-configservice-pro:
    container_name: apollo-configservice-pro
    restart: always
    image: apolloconfig/apollo-configservice:1.8.1
    ports:
      - 8081:8081
    environment:
      #修改容器启动的端口号
      SERVER_PORT: '8081'
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_PRO}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      EUREKA_INSTANCE_IP_ADDRESS: ${EUREKA_INSTANCE_IP_ADDRESS}
    volumes:
      - /tmp/logs:/opt/logs

  apollo-adminservice-pro:
    container_name: apollo-adminservice-pro
    depends_on:
      - apollo-configservice-pro
    restart: always
    image: apolloconfig/apollo-adminservice:1.8.1
    expose:
      - '8090'
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_CONFIG_PRO}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
    volumes:
      - /tmp/logs:/opt/logs  

  apollo-portal:
    container_name: apollo-portal
    depends_on:
      - apollo-adminservice-dev
      - apollo-adminservice-pro
    restart: always
    image: apolloconfig/apollo-portal:1.8.1
    ports:
      - 8070:8070
    environment:
      SPRING_DATASOURCE_URL: ${DATASOURCE_URL_PORTAL}
      SPRING_DATASOURCE_USERNAME: ${DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${DATASOURCE_PASSWORD}
      APOLLO_PORTAL_ENVS: ${APOLLO_PORTAL_ENVS}
      DEV_META: ${DEV_META}
      PRO_META: ${PRO_META}
    volumes:
      - /tmp/logs:/opt/logs

在上述的配置中,config和admin容器需要为每个环境单独配置,故有两个;而所有环境共用一个portal容器。这两个配置文件在源代码的资源目录下保存了一份供参考。

需要注意的是,config容器的默认端口是8080,由于在同一台机器上,需要修改其启动的端口,从而注册到Eureka中。这点很重要,对于多台机器,每台部署一个环境时,可不用修改。

4.4启动容器

启动命令:

docker-compose up -d

启动可能比较慢,待所有容器完全启动成功后,访问http://192.168.86.128:8070并登录。然后创建一个项目(请参考上一章节的说明,app.id等信息保持不变),如下图:

可以看到,在左侧的环境列表中,显示了配置的所有的环境。需要给每个环境新增配置并发布。

4.5测试

还是以上面的代码为例进行说明:

1)测试dev环境

在上面的配置中,dev环境对应的config的端口是8080,故把配置文件的url改成:

apollo.meta=http://192.168.86.128:8080

然后启动项目,访问http://localhost:8080/test/get,获取的是dev环境的值

2)测试pro环境

在上面的配置中,pro环境对应的config的端口是8081,故把配置文件的url改成:

apollo.meta=http://192.168.86.128:8081

然后启动项目,访问http://localhost:8080/test/get,获取的是pro环境的值

posted @ 2021-05-24 16:50  钟小嘿  阅读(1895)  评论(0编辑  收藏  举报