Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
项目在不同环境对应的不同的配置,统一管理不同环境、不同集群的配置
Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
同一份代码部署在不同的集群,可以有不同的配置,比如zk的地址等
通过命名空间(namespace)可以很方便的支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
系统 | Centos7 |
---|---|
java环境 | java1.8 |
数据库 | MariaDB-10.2.9 |
IP | 192.168.1.8 |
普通应用
普通应用指的是独立运行的程序,如Web应用程序、带有main函数的程序
公共组件
公共组件指的是发布的类库、客户端程序,不会自己独立运行,如Java的jar包、.Net的dll文件
要使用Apollo,第一步需要创建项目。
点击提交
创建成功后,会自动跳转到项目首页
项目管理员拥有以下权限:
创建项目时填写的应用负责人默认会成为项目的管理员之一,如果还需要其他人也成为项目管理员,可以按照下面步骤操作:
配置权限分为编辑和发布:
项目创建完,默认没有分配配置的编辑和发布权限,需要项目管理员进行授权。
编辑配置需要拥有这个Namespace的编辑权限,如果发现没有新增配置按钮,可以找项目管理员授权。
Apollo除了支持表格模式,逐个添加、修改配置外,还提供文本模式批量添加、修改。 这个对于从已有的properties文件迁移尤其有用。
配置只有在发布后才会真的被应用使用到,所以在编辑完配置后,需要发布配置。
发布配置需要拥有这个Namespace的发布权限,如果发现没有发布按钮,可以找项目管理员授权。
配置发布成功后,应用就可以通过Apollo客户端读取到配置了。
Apollo目前提供Java客户端,具体信息请点击Java客户端使用文档:
如果应用使用了其它语言,也可以通过直接访问Http接口获取配置,具体可以参考其它语言客户端接入指南
首先需要在Apollo中接入你的应用,具体步骤可以参考应用接入文档。
该接口会从缓存中获取配置,适合频率较高的配置拉取请求,如简单的每30秒轮询一次配置。
由于缓存最多会有一秒的延时,所以如果需要配合配置推送通知实现实时更新配置的话,请参考通过不带缓存的Http接口从Apollo读取配置
URL: {config_server_url}/configfiles/json/{appId}/{clusterName}/{namespaceName}?ip={clientIp}
Method: GET
参数说明:
参数名 | 是否必须 | 参数值 | 备注 |
---|---|---|---|
config_server_url | 是 | Apollo配置服务的地址 | |
appId | 是 | 应用的appId | |
clusterName | 是 | 集群名 | 一般情况下传入 default 即可。 如果希望配置按集群划分,可以参考集群独立配置说明做相关配置,然后在这里填入对应的集群名。 |
namespaceName | 是 | Namespace的名字 | 如果没有新建过Namespace的话,传入application即可。 如果创建了Namespace,并且需要使用该Namespace的配置,则传入对应的Namespace名字。需要注意的是对于properties类型的namespace,只需要传入namespace的名字即可,如application。对于其它类型的namespace,需要传入namespace的名字加上后缀名,如datasources.json |
ip | 否 | 应用部署的机器ip | 这个参数是可选的,用来实现灰度发布。 如果不想传这个参数,请注意URL中从?号开始的query parameters整个都不要出现。 |
该Http接口返回的是JSON格式、UTF-8编码,包含了对应namespace中所有的配置项。
返回内容Sample如下:
{
"portal.elastic.document.type":"biz",
"portal.elastic.cluster.name":"hermes-es-fws"
}
通过
{config_server_url}/configfiles/{appId}/{clusterName}/{namespaceName}?ip={clientIp}
可以获取到properties形式的配置
由于是Http接口,所以在URL组装OK之后,直接通过浏览器、或者相关的http接口测试工具访问即可。
本地测试:
# curl http://192.168.1.5:8080/configfiles/json/1001/default/application
{"redis_ip":"192.168.1.12","redis_passwd":"123456","redis_port":"6379"}
该接口会直接从数据库中获取配置,可以配合配置推送通知实现实时更新配置。
URL: {config_server_url}/configs/{appId}/{clusterName}/{namespaceName}?releaseKey={releaseKey}&ip={clientIp}
Method: GET
参数说明:
参数名 | 是否必须 | 参数值 | 备注 |
---|---|---|---|
config_server_url | 是 | Apollo配置服务的地址 | |
appId | 是 | 应用的appId | |
clusterName | 是 | 集群名 | 一般情况下传入 default 即可。 如果希望配置按集群划分,可以参考集群独立配置说明做相关配置,然后在这里填入对应的集群名。 |
namespaceName | 是 | Namespace的名字 | 如果没有新建过Namespace的话,传入application即可。 如果创建了Namespace,并且需要使用该Namespace的配置,则传入对应的Namespace名字。需要注意的是对于properties类型的namespace,只需要传入namespace的名字即可,如application。对于其它类型的namespace,需要传入namespace的名字加上后缀名,如datasources.json |
releaseKey | 否 | 上一次的releaseKey | 将上一次返回对象中的releaseKey传入即可,用来给服务端比较版本,如果版本比下来没有变化,则服务端直接返回304以节省流量和运算 |
ip | 否 | 应用部署的机器ip | 这个参数是可选的,用来实现灰度发布。 |
该Http接口返回的是JSON格式、UTF-8编码。
如果配置没有变化(传入的releaseKey和服务端的相等),则返回HttpStatus 304,response body为空。
如果配置有变化,则会返回HttpStatus 200,response body为对应namespace的meta信息以及其中所有的配置项。
返回内容Sample如下:
{
"appId": "100004458",
"cluster": "default",
"namespaceName": "application",
"configurations": {
"portal.elastic.document.type":"biz",
"portal.elastic.cluster.name":"hermes-es-fws"
},
"releaseKey": "20170430092936-dee2d58e74515ff3"
}
由于是Http接口,所以在URL组装OK之后,直接通过浏览器、或者相关的http接口测试工具访问即可。
本地测试
# curl http://192.168.1.5:8080/configs/1001/default/application
{"appId":"1001","cluster":"default","namespaceName":"application","configurations":{"redis_ip":"192.168.1.12","redis_passwd":"123456","redis_port":"6379"},"releaseKey":"20220330100056-d3ee492df675126d"}
# curl http://192.168.1.5:8080/configs/1001/default/application?releaseKey=20220330100056-d3ee492df675126d
Apollo提供了基于Http long polling的配置更新推送通知,第三方客户端可以看自己实际的需求决定是否需要使用这个功能。
如果对配置更新时间不是那么敏感的话,可以通过定时刷新来感知配置更新,刷新频率可以视应用自身情况来定,建议在30秒以上。
如果需要做到实时感知配置更新(1秒)的话,可以参考下面的文档实现配置更新推送的功能。
这里建议大家可以参考Apollo的Java实现:RemoteConfigLongPollService.java,代码量200多行,总体上还是比较简单的。
首先需要确定哪些namespace需要配置更新推送,Apollo的实现方式是程序第一次获取某个namespace的配置时就会来注册一下,我们就知道有哪些namespace需要配置更新推送了。
初始化后的结果就是得到一个notifications的Map,内容是namespaceName -> notificationId(初始值为-1)。
运行过程中如果发现有新的namespace需要配置更新推送,直接塞到notifications这个Map里面即可。
有了notifications这个Map之后,就可以请求服务了。这里先描述一下请求服务的逻辑,具体的URL参数和说明请参见后面的接口说明。
URL: {config_server_url}/notifications/v2?appId={appId}&cluster={clusterName}¬ifications={notifications}
Method: GET
参数说明:
参数名 | 是否必须 | 参数值 | 备注 |
---|---|---|---|
config_server_url | 是 | Apollo配置服务的地址 | |
appId | 是 | 应用的appId | |
clusterName | 是 | 集群名 | 一般情况下传入 default 即可。 如果希望配置按集群划分,可以参考集群独立配置说明做相关配置,然后在这里填入对应的集群名。 |
notifications | 是 | notifications信息 | 传入本地的notifications信息,注意这里需要以array形式转为json传入,如:[{“namespaceName”: “application”, “notificationId”: 100}, {“namespaceName”: “FX.apollo”, “notificationId”: 200}]。需要注意的是对于properties类型的namespace,只需要传入namespace的名字即可,如application。对于其它类型的namespace,需要传入namespace的名字加上后缀名,如datasources.json |
注1:由于服务端会hold住请求60秒,所以请确保客户端访问服务端的超时时间要大于60秒。
注2:别忘了对参数进行url encode
该Http接口返回的是JSON格式、UTF-8编码,包含了有变化的namespace和最新的notificationId。
返回内容Sample如下:
[
{
"namespaceName": "application",
"notificationId": 101
}
]
由于是Http接口,所以在URL组装OK之后,直接通过浏览器、或者相关的http接口测试工具访问即可。
Apollo从1.6.0版本开始增加访问密钥机制,从而只有经过身份验证的客户端才能访问敏感配置。如果应用开启了访问密钥,客户端发出请求时需要增加签名,否则无法获取配置。
需要设置的Header信息:
Header | Value | 备注 |
---|---|---|
Authorization | Apollo a p p I d : {appId}: appId:{signature} | appId: 应用的appId,signature:使用访问密钥对当前时间以及所访问的URL加签后的值,具体实现可以参考Signature.signature |
Timestamp | 从1970-1-1 00:00:00 UTC+0 到现在所经过的毫秒数 |
可以参考System.currentTimeMillis |
本地测试
# curl
http://192.168.1.5:8080/configfiles/json/1001/default/application
{"timestamp":"2022-03-30T16:39:11.912+0800","status":401,"error":"Unauthorized","message":"","path":"/configfiles/json/1001/default/application"}
报错 401
密钥: da01f4aab45d4e3c8b8764d99f9a31f5
获取时间戳: Timestamp=`date +%s`
curl http://192.168.1.5:8080/configfiles/json/1001/default/application -X POST -H "Content-type:application/json" -d '{"Authorization":"Apollo 1001:da01f4aab45d4e3c8b8764d99f9a31f5","Timestamp":"1648630422"}'
正常情况下,接口返回的Http状态码是200,下面列举了Apollo会返回的非200错误码说明。
客户端传入参数的错误,如必选参数没有传入等,客户端需要根据提示信息检查对应的参数是否正确。
客户端未授权,如服务端配置了访问密钥,客户端未配置或配置错误。
接口要访问的资源不存在,一般是URL或URL的参数错误,或者是对应的namespace还没有发布过配置。
接口访问的Method不正确,比如应该使用GET的接口使用了POST访问等,客户端需要检查接口访问方式是否正确。
其它类型的错误默认都会返回500,对这类错误如果应用无法根据提示信息找到原因的话,可以尝试查看服务端日志来排查问题。
https://github.com/ctripcorp/apollo-use-cases
Apollo+ES源码改造,构建民生银行的ELK日志平台配置管理中心
Apollo在有赞的实践
微服务版本切换初始设计思路
Alibaba Sentinel Push模式 规则推送至Apollo配置中心
从1.1.0版本开始,apollo-portal增加了查看权限的支持,可以支持配置某个环境只允许项目成员查看私有Namespace的配置。
这里的项目成员是指:
配置方式很简单,用超级管理员账号登录后,进入管理员工具 - 系统参数
页面新增或修改configView.memberOnly.envs
配置项即可。
Apollo从1.6.0版本开始增加访问密钥机制,从而只有经过身份验证的客户端才能访问敏感配置。如果应用开启了访问密钥,客户端需要配置密钥,否则无法获取配置。
适用于1.6.0及以上版本
Apollo从1.6.0版本开始增加访问密钥机制,从而只有经过身份验证的客户端才能访问敏感配置。如果应用开启了访问密钥,客户端需要配置密钥,否则无法获取配置。
配置方式按照优先级从高到低分别为:
1.通过Java System Property
通过Java System Propertyapollo.access-key.secret(1.9.0+) 或者 apollo.accesskey.secret(1.9.0之前)
可以通过Java的System Property apollo.access-key.secret(1.9.0+) 或者 apollo.accesskey.secret(1.9.0之前)来指定
在Java程序启动脚本中,可以指定-Dapollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0+) 或者 -Dapollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0之前)
如果是运行jar文件,需要注意格式是java -Dapollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719 -jar xxx.jar(1.9.0+) 或者 java -Dapollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719 -jar xxx.jar(1.9.0之前)
也可以通过程序指定,如System.setProperty("apollo.access-key.secret", "1cf998c4e2ad4704b45a98a509d15719");(1.9.0+) 或者 System.setProperty("apollo.accesskey.secret", "1cf998c4e2ad4704b45a98a509d15719");(1.9.0之前)
2.通过Spring Boot的配置文件
可以在Spring Boot的application.properties或bootstrap.properties中指定apollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0+) 或者 apollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0之前)
3.通过操作系统的System Environment
还可以通过操作系统的System Environment APOLLO_ACCESS_KEY_SECRET(1.9.0+) 或者 APOLLO_ACCESSKEY_SECRET(1.9.0之前)来指定
注意key为全大写
4.通过app.properties配置文件
可以在classpath:/META-INF/app.properties指定apollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0+) 或者 apollo.accesskey.secret=1cf998c4e2ad4704b45a98a509d15719(1.9.0之前)
适用于1.8.0及以上版本
1.8.0版本开始支持以下方式自定义server.properties路径,按照优先级从高到低分别为:
一.通过Java System Property apollo.path.server.properties
1.可以通过Java的System Property apollo.path.server.properties来指定
2.在Java程序启动脚本中,可以指定-Dapollo.path.server.properties=/some-dir/some-file.properties
如果是运行jar文件,需要注意格式是java -Dapollo.path.server.properties=/some-dir/some-file.properties -jar xxx.jar
3.也可以通过程序指定,如System.setProperty("apollo.path.server.properties", "/some-dir/some-file.properties");
二、通过操作系统的System EnvironmentAPOLLO_PATH_SERVER_PROPERTIES
可以通过操作系统的System Environment APOLLO_PATH_SERVER_PROPERTIES来指定
注意key为全大写,且中间是_分隔
Apollo支持API方式和Spring整合方式,该怎么选择用哪一种方式?
API方式灵活,功能完备,配置值实时更新(热发布),支持所有Java环境。
Spring方式接入简单,结合Spring有N种酷炫的玩法,如
@Value("${someKeyFromApollo:someDefaultValue}")
spring.datasource.url: ${someKeyFromApollo:someDefaultValue}
spring.datasource.url=jdbc:mysql://localhost:3306/somedb?characterEncoding=utf8
Spring方式也可以结合API方式使用,如注入Apollo的Config对象,就可以照常通过API方式获取配置了:
@ApolloConfig
private Config config; //inject config for namespace application点击复制错误复制成功
API方式是最简单、高效使用Apollo配置的方式,不依赖Spring框架即可使用。
Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
String someKey = "someKeyFromDefaultNamespace";
String someDefaultValue = "someDefaultValueForTheKey";
String value = config.getProperty(someKey, someDefaultValue);
通过上述的config.getProperty可以获取到someKey对应的实时最新的配置值。
另外,配置值从内存中获取,所以不需要应用自己做缓存。
对应开发语言支持:https://www.apolloconfig.com/#/zh/usage/third-party-sdks-user-guide
项目地址:apollo-php-client
项目地址:apollo-sdk-config
项目地址:apollo-sdk-clientd
Namespace是配置项的集合,类似于一个配置文件的概念。
个人觉得也是Apollo的比较重要和核心的知识点!
Apollo在创建项目的时候,都会默认创建一个“application”的Namespace。顾名思义,“application”是给应用自身使用的,熟悉Spring Boot的同学都知道,Spring Boot项目都有一个默认配置文件application.yml。在这里application.yml就等同于“application”的Namespace。对于90%的应用来说,“application”的Namespace已经满足日常配置使用场景了。
Config config = ConfigService.getAppConfig();
Config config = ConfigService.getConfig(namespaceName);
配置文件有多种格式,例如:properties、xml、yml、yaml、json等。同样Namespace也具有这些格式。在Portal UI中可以看到“application”的Namespace上有一个“properties”标签,表明“application”是properties格式的。
注1:非properties格式的namespace,在客户端使用时需要调用
ConfigService.getConfigFile(String namespace, ConfigFileFormat configFileFormat)
来获取,如果使用Http接口直接调用时,对应的namespace参数需要传入namespace的名字加上后缀名,如datasources.json。
注2:apollo-client 1.3.0版本开始对yaml/yml做了更好的支持,使用起来和properties格式一致:
Config config = ConfigService.getConfig("application.yml");
,Spring的注入方式也和properties一致。
private (私有的)
public (公共的)
这里的获取权限是相对于Apollo客户端来说的。
private权限的Namespace:只能被所属的应用获取到。一个应用尝试获取其它应用private的Namespace,Apollo会报“404”异常。
public权限的Namespace: 能被任何应用获取。
Namespace类型有三种:
具有private权限。例如上文提到的“application” 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
关联类型使用场景:
举一个实际使用的场景。假设RPC框架的配置(如:timeout)有以下要求:
如下图所示,有三个应用:应用A、应用B、应用C。
应用A有两个私有类型的Namespace:application和NS-Private,以及一个关联类型的Namespace:NS-Public。
应用B有一个私有类型的Namespace:application,以及一个公共类型的Namespace:NS-Public。
应用C只有一个私有类型的Namespace:application
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v11
appConfig.getProperty("k2", null); // k2 = v21
//NS-Private
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", null); // k1 = v3
privateConfig.getProperty("k3", null); // k3 = v4
//NS-Public,覆盖公共类型配置的情况,k4被覆盖
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v6 cover
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7点击复制错误复制成功
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v12
appConfig.getProperty("k2", null); // k2 = null
appConfig.getProperty("k3", null); // k3 = v32
//NS-Private,由于没有NS-Private Namespace 所以获取到default value
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", "default value");
//NS-Public
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v5
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7点击复制错误复制成功
//application
Config appConfig = ConfigService.getAppConfig();
appConfig.getProperty("k1", null); // k1 = v12
appConfig.getProperty("k2", null); // k2 = null
appConfig.getProperty("k3", null); // k3 = v33
//NS-Private,由于没有NS-Private Namespace 所以获取到default value
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.getProperty("k1", "default value");
//NS-Public,公共类型的Namespace,任何项目都可以获取到
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.getProperty("k4", null); // k4 = v5
publicConfig.getProperty("k6", null); // k6 = v6
publicConfig.getProperty("k7", null); // k7 = v7点击复制错误复制成功
以上代码例子中可以看到,在客户端Namespace映射成一个Config对象。Namespace配置变更的监听器是注册在Config对象上。
所以在应用A中监听application的Namespace代码如下:
Config appConfig = ConfigService.getAppConfig();
appConfig.addChangeListener(new ConfigChangeListener() {
public void onChange(ConfigChangeEvent changeEvent) {
//do something
}
})
在应用A中监听NS-Private的Namespace代码如下:
Config privateConfig = ConfigService.getConfig("NS-Private");
privateConfig.addChangeListener(new ConfigChangeListener() {
public void onChange(ConfigChangeEvent changeEvent) {
//do something
}
})
在应用A、应用B、应用C中监听NS-Public的Namespace代码如下:
Config publicConfig = ConfigService.getConfig("NS-Public");
publicConfig.addChangeListener(new ConfigChangeListener() {
public void onChange(ConfigChangeEvent changeEvent) {
//do something
}
})
配置项统一存储在ApolloConfigDB.ServerConfig表中,需要注意每个环境的ApolloConfigDB.ServerConfig都需要单独配置,修改完一分钟实时生效。
这是一个功能开关,如果配置为true的话,那么一次配置发布只能是一个人修改,另一个发布。
生产环境建议开启此选项
以下配置除了支持在数据库中配置以外,也支持通过-D参数、application.properties等配置,且-D参数、application.properties等优先级高于数据库中的配置
配置项统一存储在ApolloPortalDB.ServerConfig表中,也可以通过管理员工具 - 系统参数
页面进行配置,无特殊说明则修改完一分钟实时生效。
默认值是dev,如果portal需要管理多个环境的话,以逗号分隔即可(大小写不敏感),如:
DEV,FAT,UAT,PRO
名词解释:
DEV(Development environment)
开发环境,用于开发者调试使用
FAT(Feature Acceptance Test environment)
功能验收测试环境,用于软件测试者测试使用
UAT(User Acceptance Test environment)
用户验收测试环境,用于用户测试验收使用
PRO(Production environment)
生产环境
修改完需要重启生效。
注1:一套Portal可以管理多个环境,但是每个环境都需要独立部署一套Config Service、Admin Service和ApolloConfigDB,具体请参考:2.1.2 创建ApolloConfigDB,3.2 调整ApolloConfigDB配置,2.2.1.1.2 配置数据库连接信息,另外如果是为已经运行了一段时间的Apollo配置中心增加环境,别忘了参考2.1.2.4 从别的环境导入ApolloConfigDB的项目数据对新的环境做初始化。
注2:只在数据库添加环境是不起作用的,还需要为apollo-portal添加新增环境对应的meta server地址,具体参考:2.2.1.1.2.4 配置apollo-portal的meta service信息。apollo-client在新的环境下使用时也需要做好相应的配置,具体参考:1.2.2 Apollo Meta Server。
注3:如果希望添加自定义的环境名称,具体步骤可以参考Portal如何增加环境。
注4:1.1.0版本增加了系统信息页面(
管理员工具
->系统信息
),可以通过该页面检查配置是否正确
Apollo Portal需要在不同的环境访问不同的meta service(apollo-configservice)地址,所以我们需要在配置中提供这些信息。默认情况下,meta service和config service是部署在同一个JVM进程,所以meta service的地址就是config service的地址。
对于1.6.0及以上版本,可以通过ApolloPortalDB.ServerConfig中的配置项来配置Meta Service地址,详见apollo.portal.meta.servers - 各环境Meta Service列表
使用程序员专用编辑器(如vim,notepad++,sublime等)打开apollo-portal-x.x.x-github.zip
中config
目录下的apollo-env.properties
文件。
假设DEV的apollo-configservice未绑定域名,地址是192.168.1.5:8080,PRO的apollo-configservice绑定了域名apollo.chuanqu.ltd,那么可以如下修改各环境meta service服务地址,格式为${env}.meta=http://${config-service-url:port}
,如果某个环境不需要,也可以直接删除对应的配置项(如lpt.meta):
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
除了通过apollo-env.properties
方式配置meta service以外,apollo也支持在运行时指定meta service(优先级比apollo-env.properties
高):
通过Java System Property
${env}_meta
${env}_meta
来指定java -Ddev_meta=http://config-service-url -jar xxx.jar
System.setProperty("dev_meta", "http://config-service-url");
通过操作系统的System Environment
${ENV}_META
DEV_META=http://config-service-url
_
分隔注1: 为了实现meta service的高可用,推荐通过SLB(Software Load Balancer)做动态负载均衡
注2: meta service地址也可以填入IP,0.11.0版本之前只支持填入一个IP。从0.11.0版本开始支持填入以逗号分隔的多个地址(PR #1214),如
http://1.1.1.1:8080,http://2.2.2.2:8080
,不过生产环境还是建议使用域名(走slb),因为机器扩容、缩容等都可能导致IP列表的变化。