都什么年代了,你还在手动配置吗

15天前

Governor如何与Apollo集成?


转载本文需注明出处:微信公众号EAWorld,违者必究。


前言:

随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址等等,对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。


1、Apollo介绍

在EOS Platform中,Governor(微服务管理平台)集成了Apollo作为配置中心,在介绍之前,我们先来简单了解一下Apollo吧。

Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性。服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。

Apollo支持4个维度管理Key-Value格式的配置:

  1. application (应用):项目的AppId对应Governor系统里的某个应用,SYS.AppId对应域里的某个系统

  2. environment (环境):在Governor中默认填写DEV,因为现在的需求只需要用到一个开发环境,不需要设置多环境

  3. cluster (集群):在Governor中对应实例组

  4. namespace (命名空间):在Governor中对应配置组

2、核心概念——Namespace

  1. 格式:namespace就相当于Springboot项目中的配置文件,例如namespace中有默认的application,格式为properties,则对应着application.properties。配置文件有多种格式,例如:properties、xml、yml、yaml、json等。同样namespace也具有这些格式。

  2. 权限:namespace的获取权限分为两种:private和public。

    private权限的namespace,只能被所属的应用获取到。一个应用尝试获取其它应用private的namespace,Apollo会报“404”异常。

    public权限的namespace,能被任何应用获取。

  3. 类型:namespace类型有三种:私有类型、公共类型、关联类型。

    私有类型的namespace具有private权限。例如上文提到的“application” Namespace就是私有类型。公共类型的namespace具有public权限。

    公共类型的namespace相当于游离于应用之外的配置,且通过namespace的名称去标识公共namespace,所以公共的namespace的名称必须全局唯一。

    关联类型又可称为继承类型,关联类型具有private权限。关联类型的namespace继承于公共类型的namespace,用于覆盖公共namespace的某些配置。例如公共的namespace有两个配置项:k1 = v1、k2 = v2,然后应用A有一个关联类型的namespace关联了此公共namespace,且覆盖了配置项k1,值为v3。那么在应用A实际运行时,获取到的公共namespace的配置为:k1 = v3、k2 = v2。

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的各种功能了。

关于作者酸奶终结者,普元Java工程师,曾参与上海银行、EOS platform等项目,我是Java螺丝钉,哪里需要哪里拧。


关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!

COMMENTS

需要 后方可回复
如果没有账号可以 一个帐号。