前言:
随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址等等,对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。
1、Apollo介绍
在EOS Platform中,Governor(微服务管理平台)集成了Apollo作为配置中心,在介绍之前,我们先来简单了解一下Apollo吧。
Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
Apollo支持4个维度管理Key-Value格式的配置:
2、核心概念——Namespace
3、总体设计
Apollo总体设计
从下往上看:
Config Service 提供配置的读取、推送等功能,服务端使用Spring DeferredResult实现异步化,从而大大增加长连接数量,服务对象是Apollo客户端
Admin Service 提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)
Config Service 和 Admin Service 都是多实例、无状态部署,所以需要将自己注册到 Eureka 中并保持心跳,也为了Governor从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进程中
4、Governor如何与Apollo集成
在Governor里,RuntimeSettings.java是储存所有域设置的数据库表的实体类,和其它设置的通用属性有id、category、type、urls、configJson、name、desc、createdDate、lastModifiedDate、domainId等,这里我们只关注配置中心,以下属性是放在configJson这个字段里的。
除了地址,它们都有固定的值,需要手动填写,env=DEV,orgId=TEST1,orgName=样例部门1,username=apollo,password=admin,如下图:
Apollo的信息存到表里之后,我们就可以通过拼接url的方式和Apollo进行交互了。所有的url都写在ApolloService里,如下图所示:
接下来以某项目导入配置文件的功能为例,看看我们应该如何将数据处理并成功导入到Apollo里进行发布。
当传入一份properties文件时,我们通过工具类readProperties()取出里面的key-value对放在一个map里(textItems),再通过配置组id查到一个配置组对象,加上releaseInfo,调用ApplicationConfigService的saveItemKVs方法。这个方法对数据做了最初的处理,为调用Apollo的接口提供了必要的信息。ApolloIds提供了appId、clusterName、namespaceName等属性,ApolloConfig提供了env、username、password等属性,由于ApolloConfig继承了Config类,所以它还可以获取到Apollo的地址。getApolloIds和getApolloConfig最终会返回appId、clusterName、namespaceName、url等,因为我们需要这些信息才能定位到一份具体的配置文件。
在调用createTextItems方法之后,我们传入的配置文件里的key-value已经变成了下面的这个Apollo认识的样子:{"configText":"key-01 = value-01\nkey-02 = value-02\n","namespaceId":73,"format":"properties"}。addId、namespace、cluster等信息也有了,在saveTextItems方法里将它们拼接在一起,可以向Apollo发请求了。
我们最后发送的请求应为PUT请求:
http://10.15.15.91:18083/apps/ORDER-MANAGER-DEV/envs/DEV/clusters/default/namespaces/eos_logger_level/items
到Apollo上查看:
成功发布了,大功告成。
Governor集成Apollo的方式就是通过直接拼接url来调用Apollo的接口,我们可以通过在Apollo界面按f12查看它的url长什么样子,然后全部定义在apolloService中,把存在数据库里的信息取出来一一放入url,需要什么拼什么,这样就可以使用Apollo的各种功能了。