Apollo配置中心使用

https://blog.youkuaiyun.com/Dbh321/article/details
apollo官网源码:https://github.com/apolloconfig/apollo
apollo使用文档:https://www.apolloconfig.com/#/zh/README
https://www.apolloconfig.com/#/zh/README

配置的概念

按照我们的理解,配置有以下几个属性:
配置是独立于程序的只读变量
配置首先是独立于程序的,同一份程序在不同的配置下会有不同的行为。
其次,配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置。
常见的配置有:DB Connection Str、Thread Pool Size、Buffer Size、Request Timeout、Feature Switch、Server Urls等。
配置伴随应用的整个生命周期
配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。
配置可以有多种加载方式
配置也有很多种加载方式,常见的有程序内部hard code,配置文件,环境变量,启动参数,基于数据库等
配置需要治理
权限控制
由于配置能改变程序的行为,不正确的配置甚至能引起灾难,所以对配置的修改必须有比较完善的权限控制
不同环境、集群配置管理
同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理
框架类组件配置管理
还有一类比较特殊的配置 - 框架类组件配置,比如CAT客户端的配置。
虽然这类框架类组件是由其他团队开发、维护,但是运行时是在业务实际应用内的,所以本质上可以认为框架类组件也是应用的一部分。
这类组件对应的配置也需要有比较完善的管理方式。

apollo基本概念

  1. application (应用)
    这个很好理解,就是实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置
    每个应用都需要有唯一的身份标识 – appId
    例如aicall是一个应用
  2. environment (环境)
    配置对应的环境,Apollo客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置
    我们认为环境和代码无关,同一份代码部署在不同的环境就应该能够获取到不同环境的配置
    所以环境默认是通过读取机器上的配置(server.properties中的env属性)指定的,不过为了开发方便,我们也支持运行时通过System Property等指定。
    例如UAT,SIT,PRO
  3. cluster (集群)
    一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。
    对不同的cluster,同一个配置可以有不一样的值,如zookeeper地址。
    集群默认是通过读取机器上的配置(server.properties中的idc属性)指定的,不过也支持运行时通过System Property指定
    目前aicall系统未做集群区分
  4. namespace (命名空间)
    一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等
    应用可以直接读取到公共组件的配置namespace,如DAL,RPC等
    应用也可以通过继承公共组件的配置namespace来对公共组件的配置做调整,如DAL的初始数据库连接数
    可以为每个模块,做一个单独的namespace
    模块概要
    Config Service
    提供配置获取接口
    提供配置更新推送接口(基于Http long polling)
    服务端使用Spring DeferredResult实现异步化,从而大大增加长连接数量
    目前使用的tomcat embed默认配置是最多10000个连接(可以调整),使用了4C8G的虚拟机实测可以支撑10000个连接,所以满足需求(一个应用实例只会发起一个长连接)。
    接口服务对象为Apollo客户端
    Admin Service
    提供配置管理接口
    提供配置修改、发布等接口
    接口服务对象为Portal
    Meta Server
    ● Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port)
    ● Client通过域名访问Meta Server获取Config Service服务列表(IP+Port)
    ● Meta Server从Eureka获取Config Service和Admin Service的服务信息,相当于是一个Eureka Client
    ● 增设一个Meta Server的角色主要是为了封装服务发现的细节,对Portal和Client而言,永远通过一个Http接口获取Admin Service和Config Service的服务信息,而不需要关心背后实际的服务注册和发现组件
    ● Meta Server只是一个逻辑角色,在部署时和Config Service是在一个JVM进程中的,所以IP、端口和Config Service一致
    Eureka
    ● 基于Eureka和Spring Cloud Netflix提供服务注册和发现
    ● Config Service和Admin Service会向Eureka注册服务,并保持心跳
    ● 为了简单起见,目前Eureka在部署时和Config Service是在一个JVM进程中的(通过Spring Cloud Netflix)
    Portal
    ● 提供Web界面供用户管理配置
    ● 通过Meta Server获取Admin Service服务列表(IP+Port),通过IP+Port访问服务
    ● 在Portal侧做load balance、错误重试
    Client
    ● Apollo提供的客户端程序,为应用提供配置获取、实时更新等功能
    ● 通过Meta Server获取Config Service服务列表(IP+Port),通过IP+Port访问服务
    ● 在Client侧做load balance、错误重试

功能实现

配置发布后的实时推送设计
在配置中心中,一个重要的功能就是配置发布后实时推送到客户端。
在这里插入图片描述

上图简要描述了配置发布的大致过程:

  1. 用户在Portal操作配置发布
  2. Portal调用Admin Service的接口操作发布
  3. Admin Service发布配置后,发送ReleaseMessage给各个Config Service
  4. Config Service收到ReleaseMessage后,通知对应的客户端
    发送ReleaseMessage的实现方式
    Admin Service在配置发布后,需要通知所有的Config Service有配置发布,从而Config Service可以通知对应的客户端来拉取最新的配置。
    从概念上来看,这是一个典型的消息使用场景,Admin Service作为producer发出消息,各个Config Service作为consumer消费消息。通过一个消息组件(Message Queue)就能很好的实现Admin Service和Config Service的解耦。
    在实现上,考虑到Apollo的实际使用场景,以及为了尽可能减少外部依赖,我们没有采用外部的消息中间件,而是通过数据库实现了一个简单的消息队列。
    实现方式如下:
  5. Admin Service在配置发布后会往ReleaseMessage表插入一条消息记录,消息内容就是配置发布的AppId+Cluster+Namespace
  6. Config Service有一个线程会每秒扫描一次ReleaseMessage表,看看是否有新的消息记录
  7. Config Service如果发现有新的消息记录,那么就会通知到所有的消息监听器(ReleaseMessageListener),如NotificationControllerV2
  8. NotificationControllerV2得到配置发布的AppId+Cluster+Namespace后,会通知对应的客户端
    示意图如下:

Config Service通知客户端的实现方式
实现方式如下:

  1. 客户端会发起一个Http请求到Config Service的notifications/v2接口

  2. NotificationControllerV2不会立即返回结果,而是通过Spring DeferredResult把请求挂起

  3. 如果在60秒内没有该客户端关心的配置发布,那么会返回Http状态码304给客户端

  4. 如果有该客户端关心的配置发布,NotificationControllerV2会调用DeferredResult的setResult方法,传入有配置变化的namespace信息,同时该请求会立即返回。客户端从返回的结果中获取到配置变化的namespace后,会立即请求Config Service获取该namespace的最新配置。
    客户端实现

  5. 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)

  6. 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。
    ○ 这是一个fallback机制,为了防止推送机制失效导致配置不更新
    ○ 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
    ○ 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval来覆盖,单位为分钟。

  7. 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中

  8. 客户端会把从服务端获取到的配置在本地文件系统缓存一份
    ○ 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置

  9. 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知

接入参数配置
Apollo客户端依赖于AppId,Apollo Meta Server等环境信息来工作
AppId设置方式(优先级由低到高):

  1. System Property -Dapp.id=YOUR-APP-ID
  2. 操作系统的System Environment APP_ID=YOUR-APP-ID
  3. Spring Boot application.properties app.id=YOUR-APP-ID 该配置方式不适用于多个war包部署在同一个tomcat的使用场景
  4. app.properties app.id=YOUR-APP-ID
    Apollo Meta Server设置方式(优先级由低到高):
  5. 通过Java System Property apollo.meta
    ○ 可以通过Java的System Property apollo.meta来指定
    ○ 在Java程序启动脚本中,可以指定-Dapollo.meta=http://config-service-url
    ■ 如果是运行jar文件,需要注意格式是java -Dapollo.meta=http://config-service-url -jar xxx.jar
    ○ 也可以通过程序指定,如System.setProperty(“apollo.meta”, “http://config-service-url”);
  6. 通过Spring Boot的配置文件
    ○ 可以在Spring Boot的application.properties或bootstrap.properties中指定apollo.meta=http://config-service-url该配置方式不适用于多个war包部署在同一个tomcat的使用场景
  7. 通过操作系统的System Environment APOLLO_META
    ○ 可以通过操作系统的System Environment APOLLO_META来指定
    ○ 注意key为全大写,且中间是_分隔
  8. 通过server.properties配置文件
    ○ 可以在server.properties配置文件中指定apollo.meta=http://config-service-url
    ○ 对于Mac/Linux,默认文件位置为/opt/settings/server.properties
    ○ 对于Windows,默认文件位置为C:\opt\settings\server.properties
  9. 通过app.properties配置文件
    ○ 可以在classpath:/META-INF/app.properties指定apollo.meta=http://config-service-url
  10. 通过Java system property ${env}_meta
    ○ 如果当前env是dev,那么用户可以配置-Ddev_meta=http://config-service-url
    ○ 使用该配置方式,那么就必须要正确配置Environment,详见1.2.4.1 Environment
  11. 通过操作系统的System Environment ${ENV}_META (1.2.0版本开始支持)
    ○ 如果当前env是dev,那么用户可以配置操作系统的System Environment DEV_META=http://config-service-url
    ○ 注意key为全大写
    ○ 使用该配置方式,那么就必须要正确配置Environment
  12. 通过apollo-env.properties文件
    ○ 用户也可以创建一个apollo-env.properties,放在程序的classpath下,或者放在spring boot应用的config目录下
    ○ 使用该配置方式,那么就必须要正确配置Environment
    ○ 文件内容形如:dev.meta=http://1.1.1.1:8080 fat.meta=http://apollo.fat.xxx.com uat.meta=http://apollo.uat.xxx.com pro.meta=http://apollo.xxx.com
    Environment可以通过以下3种方式的任意一个配置:
  13. 通过Java System Property
    ○ 可以通过Java的System Property env来指定环境
    ○ 在Java程序启动脚本中,可以指定-Denv=YOUR-ENVIRONMENT
    ■ 如果是运行jar文件,需要注意格式是java -Denv=YOUR-ENVIRONMENT -jar xxx.jar
    ○ 注意key为全小写
  14. 通过操作系统的System Environment
    ○ 还可以通过操作系统的System Environment ENV来指定
    ○ 注意key为全大写
  15. 通过配置文件
    ○ 最后一个推荐的方式是通过配置文件来指定env=YOUR-ENVIRONMENT
    ○ 对于Mac/Linux,默认文件位置为/opt/settings/server.properties
    ○ 对于Windows,默认文件位置为C:\opt\settings\server.properties

文件内容形如:env=DEV
目前,env支持以下几个值(大小写不敏感):
● DEV
○ Development environment
● FAT
○ Feature Acceptance Test environment
● UAT
○ User Acceptance Test environment
● PRO
○ Production environment

加密支持
支持jasypt-spring-boot自动实现加解密功能。
使用时将加密后的数据配置到applo中,添加配置时使用ENC()包含配置,如加密配置为xxx,则ENC(xxx)
在项目的配置文件中,增加加密密钥的配置,例如:
jasypt.encryptor.password = klklklklklklklkl

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思静鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值