Vert.x Config
您可以使用 Vert.x Config 配置 Vert.x 应用。 它:
-
提供多种配置语法(JSON,properties,Yaml(extension), Hocon(extension)……)
-
提供多种配置中心,例如文件、目录、HTTP、git(extension)、Redis(extension)、 系统参数和环境变量。
-
让您定义执行顺序以及覆盖规则
-
支持运行时重新定义
概念
该库主要围绕:
Config Retriever 的实例化,并用于 Vert.x 应用。 它配置了一系列配置中心(Configuration store) Configuration store 定义了配置信息读取路径以及格式(默认JSON)
配置以 JSON 对象格式被接收。
使用 Config Retriever
要使用 Config Retriever, 则需要添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
以上工作完成之后,您第一件要做的事情就是实例化 ConfigRetriever
:
ConfigRetriever retriever = ConfigRetriever.create(vertx);
默认情况下,Config Retriever 可以使用下列配置中心进行配置 (按下列顺序):
-
Vert.x verticle
config()
-
系统参数
-
环境变量
-
conf/config.json
文件。这个路径可以用vertx-config-path
系统参数或者VERTX_CONFIG_PATH
环境变量所覆盖。
您可以指定您自己的配置中心:
ConfigStoreOptions httpStore = new ConfigStoreOptions()
.setType("http")
.setConfig(new JsonObject()
.put("host", "localhost").put("port", 8080).put("path", "/conf"));
ConfigStoreOptions fileStore = new ConfigStoreOptions()
.setType("file")
.setConfig(new JsonObject().put("path", "my-config.json"));
ConfigStoreOptions sysPropsStore = new ConfigStoreOptions().setType("sys");
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.addStore(httpStore).addStore(fileStore).addStore(sysPropsStore);
ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
如下可见更多关于覆盖规则和可用配置中心的细节信息。每一种配置中心都可以标记为 可选的(optional)
。
如果正在从一个可选的配置中心中获取(或处理)配置的时候,捕获到一个失败事件,那么这个失败事件会被日志所记录,但是执行过程并没有失败。
相反会返回一个空的 Json 对象(即:{}
)。
想要将一个配置中心标记为可选的,那么就使用 optional
属性:
ConfigStoreOptions fileStore = new ConfigStoreOptions()
.setType("file")
.setOptional(true)
.setConfig(new JsonObject().put("path", "my-config.json"));
ConfigStoreOptions sysPropsStore = new ConfigStoreOptions().setType("sys");
ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore).addStore(sysPropsStore);
ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
获取 Config Retriever 示例后,可按如下所示 获取 配置:
retriever.getConfig(ar -> {
if (ar.failed()) {
// 获取配置失败
} else {
JsonObject config = ar.result();
}
});
覆盖规则
配置中心的声明顺序非常重要, 因为它定义了覆盖顺序。对于冲突的key, 后 声明的配置中心会覆盖之前的。我们举个例子。 我们有两个配置中心:
-
A
提供{a:value, b:1}
配置 -
B
提供{a:value2, c:2}
配置
以 A,B 的顺序声明配置,最终配置应该为:
{a:value2, b:1, c:2}
。
如果您将声明的顺序反过来(B,A),那么您会得到 {a:value, b:1, c:2}
。
使用配置
获取到的配置可用于:
-
配置verticles,
-
配置端口,客户端,location等等,
-
配置Vert.x自身
本节给出几个使用示例。
配置一个单独的Verticle
以下示例代码可以放到 verticle 的 start
方法中。它获取了配置
(用默认配置中心),并且利用该配置创建了一个HTTP服务。
ConfigRetriever retriever = ConfigRetriever.create(vertx);
retriever.getConfig(json -> {
JsonObject result = json.result();
vertx.createHttpServer()
.requestHandler(req -> result.getString("message"))
.listen(result.getInteger("port"));
});
配置一组Verticles
以下示例用 verticles.json
文件中的配置创建了2个verticle
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "verticles.json"))));
retriever.getConfig(json -> {
JsonObject a = json.result().getJsonObject("a");
JsonObject b = json.result().getJsonObject("b");
vertx.deployVerticle(GreetingVerticle.class.getName(), new DeploymentOptions().setConfig(a));
vertx.deployVerticle(GreetingVerticle.class.getName(), new DeploymentOptions().setConfig(b));
});
配置Vert.x自身
您也可以直接配置Vert.x自身。您需要一个临时Vert.x对象用来获取配置。 然后创建实际Vert.x实例:
Vertx vertx = Vertx.vertx();
// 创建 config retriever
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "vertx.json"))));
// 获取配置
retriever.getConfig(json -> {
JsonObject result = json.result();
// 关闭vertx对象,我们再也用不到它了
vertx.close();
// 用获取到的配置创建一个新的Vert.x实例
VertxOptions options = new VertxOptions(result);
Vertx newVertx = Vertx.vertx(options);
// 部署您的Verticle
newVertx.deployVerticle(GreetingVerticle.class.getName(), new DeploymentOptions().setConfig(result.getJsonObject("a")));
});
向事件总线传播配置变更
当配置变化时,Vert.x Config 会通知您。如果您需要对这个事件做出响应,您需要自己实现这个逻辑。 例如,您可以下线/重新部署verticle或者向事件总线发送新的配置。 下列实例展示了后者的场景。它向事件总线发送新的配置。 与事件关联的 verticle可以监听这个address并更新自身:
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "verticles.json"))));
retriever.getConfig(json -> {
//...
});
retriever.listen(change -> {
JsonObject json = change.getNewConfiguration();
vertx.eventBus().publish("new-configuration", json);
});
可用的配置中心
Config Retriever 提供一系列的配置中心和配置格式。 更多可用的配置中心请参考本文后续介绍的扩展,您可以也自己实现.
配置的结构
每一个声明的数据配置中心必须要指定 类型(type)
,它也定义了 格式(format)
。
如果没有设置,默认用JSON。
一些配置中心要求额外的配置(比如路径……)。
这项配置需要用 setConfig
方法传入一个JSON 对象来指定。
文件
此配置中心仅从文件中获得配置。 他支持所有的格式。
ConfigStoreOptions file = new ConfigStoreOptions()
.setType("file")
.setFormat("properties")
.setConfig(new JsonObject().put("path", "path-to-file.properties"));
path
配置项是必填项。
JSON
JSON配置中心按原样提供给定的JSON配置
ConfigStoreOptions json = new ConfigStoreOptions()
.setType("json")
.setConfig(new JsonObject().put("key", "value"));
这个配置中心仅仅支持JSON格式。
环境变量
这个配置中心将环境变量转换为用于全局配置的 JSON obejct
ConfigStoreOptions env = new ConfigStoreOptions()
.setType("env");
这个配置中心不支持 format
配置项。
获取到的值默认会被传输到JSON兼容的结构当中(数字,字符串,布尔,JSON 对象和JSON 数组)。
如果要避免这种转换,则需要配置 raw-data
属性:
ConfigStoreOptions env = new ConfigStoreOptions()
.setType("env")
.setConfig(new JsonObject().put("raw-data", true));
您可以配置 raw-data
属性(默认为 false
)。如果 raw-data
为 true
,
则不会对值进行转换。用 config.getString(key)
方法,您会得到原始值。
当操作大整型数时,这很有用。
如果您想选择一系列key值来导入,那么用 keys
属性。他将未选择的key值都过滤掉了。
key必须独立列出:
ConfigStoreOptions env = new ConfigStoreOptions()
.setType("env")
.setConfig(new JsonObject().put("keys", new JsonArray().add("SERVICE1_HOST").add("SERVICE2_HOST")));
系统参数
这个配置中心将系统参数转换为用于全局配置的 JSON 对象
ConfigStoreOptions sys = new ConfigStoreOptions()
.setType("sys")
.setConfig(new JsonObject().put("cache", false));
这个配置中心不支持 format
配置项。
您可以配置 cache
属性(默认为 true
)
来决定是否在第一次访问时缓存系统参数而后不再重新加载他们。
您也可以配置 raw-data
属性(默认为 false
)。如果 raw-data
为 true
,
则不会对值进行转换。用 config.getString(key)
方法,您会得到原始值。
当操作大整型数时,这很有用。
此外,亦存在有 hierarchical
属性(默认为 false
)。如果 hierarchical
为 true
,
则系统属性将被解析为嵌套的 JSON 对象,使用点分隔的属性名称作为 JSON 对象中的路径。
例子:
ConfigStoreOptions sysHierarchical = new ConfigStoreOptions()
.setType("sys")
.setConfig(new JsonObject().put("hierarchical", true));
java -Dserver.host=localhost -Dserver.port=8080 -jar your-application.jar
这将会读取系统属性为 JSON 对象相当于
{
"server": {
"host": "localhost",
"port": 8080
}
}
HTTP
这个配置中心从HTTP地址获取配置。 可以用任何支持的格式。
ConfigStoreOptions http = new ConfigStoreOptions()
.setType("http")
.setConfig(new JsonObject()
.put("host", "localhost")
.put("port", 8080)
.put("path", "/A"));
他创建了一个带有 配置中心的配置
的Vert.x HTTP客户端(见下一小段)。
为了简化配置,您也可以用
host
, port
和 path
属性来分别配置他们。
您也可以用 headers
属性来配置可选的HTTP请求头,
timeout
属性配置超时时间(默认3000毫秒),
followRedirects
属性来指定是否重定向(默认情况下为false)。
ConfigStoreOptions http = new ConfigStoreOptions()
.setType("http")
.setConfig(new JsonObject()
.put("defaultHost", "localhost")
.put("defaultPort", 8080)
.put("ssl", true)
.put("path", "/A")
.put("headers", new JsonObject().put("Accept", "application/json")));
事件总线
这个配置中心从事件总线获取配置。 此种配置中心可以让您在本地和分布式组件之间传输配置。
ConfigStoreOptions eb = new ConfigStoreOptions()
.setType("event-bus")
.setConfig(new JsonObject()
.put("address", "address-getting-the-conf")
);
这个配置中心支持任何格式。
目录
这个配置中心和 文件
配置中心很相似,
但是它并不是去读单个文件,而是从一个目录中读取多个文件
这个配置中心必须要配置如下项:
-
一个
path
- 读取文件的根目录 -
至少一个
fileset
- 一个用于选择文件的对象 -
对于properties文件,您可以用
raw-data
属性来禁止类型转换。
每一个 fileset
都包含:
-
一个
pattern
:一个Ant风格的pattern用于选择文件。 这个pattern应用于相对当前工作目录的相对路径。 -
一个可选的
format
,它制定了文件的格式(每一个fileset可以用一个不同的format, 但是同一个fileset共用一个format)
ConfigStoreOptions dir = new ConfigStoreOptions()
.setType("directory")
.setConfig(new JsonObject().put("path", "config")
.put("filesets", new JsonArray()
.add(new JsonObject().put("pattern", "dir/*json"))
.add(new JsonObject().put("pattern", "dir/*.properties")
.put("format", "properties"))
));
ConfigStoreOptions dirWithRawData = new ConfigStoreOptions()
.setType("directory")
.setConfig(new JsonObject().put("path", "config")
.put("filesets", new JsonArray()
.add(new JsonObject().put("pattern", "dir/*json"))
.add(new JsonObject().put("pattern", "dir/*.properties")
.put("format", "properties").put("raw-data", true))
));
Properties 文件和原始数据
Vert.x Config可以读一个properties文件。当读取一个这样的文件,您可以传入 raw-data
参数来提醒Vert.x不要转换它的值。这在操作大整型数字时很有用。
这些值可以用 config.getString(key)
方法来获取。
ConfigStoreOptions propertyWithRawData = new ConfigStoreOptions()
.setFormat("properties")
.setType("file")
.setConfig(new JsonObject().put("path", "raw.properties").put("raw-data", true)
);
一些properties配置可能本来就是多级的。
当读取到这样的文件,您可以设置 hierarchical
参数来提醒Vert.x,当操作这个多级属性时,则将配置转换到 Json 对象当中,
这与前述方法设置扁平结构形成了对比。
例如:
server.host=localhost server.port=8080 multiple.values=1,2,3
获取值:
ConfigStoreOptions propertyWithHierarchical = new ConfigStoreOptions()
.setFormat("properties")
.setType("file")
.setConfig(new JsonObject().put("path", "hierarchical.properties").put("hierarchical", true)
);
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.addStore(propertyWithHierarchical);
ConfigRetriever configRetriever = ConfigRetriever.create(Vertx.vertx(), options);
configRetriever.configStream().handler(config -> {
String host = config.getJsonObject("server").getString("host");
Integer port = config.getJsonObject("server").getInteger("port");
JsonArray multiple = config.getJsonObject("multiple").getJsonArray("values");
for (int i = 0; i < multiple.size(); i++) {
Integer value = multiple.getInteger(i);
}
});
监听配置的变更
Configuration Retriever 定期获取配置信息, 如果获取到的结果与当前不同,那么您可以重新配置应用。 默认情况下配置每5秒重新加载一次。
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.setScanPeriod(2000)
.addStore(store1)
.addStore(store2);
ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.getConfig(json -> {
// 初始化获取配置
});
retriever.listen(change -> {
// 之前的配置
JsonObject previous = change.getPreviousConfiguration();
// 新配置
JsonObject conf = change.getNewConfiguration();
});
以流的方式读取配置
ConfigRetriever
提供了一个访问配置流的方法。
这是一个 JsonObject
的 ReadStream
。通过注册正确的处理器集合,您
会收到通知:
-
当获取到一个新的配置
-
当获取配置时发生错误
-
当 configuration retriever 关闭(即
endHandler
被调用)
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.setScanPeriod(2000)
.addStore(store1)
.addStore(store2);
ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.configStream()
.endHandler(v -> {
// retriever 关闭
})
.exceptionHandler(t -> {
// 当获取配置时捕获到错误
})
.handler(conf -> {
// 配置
});
处理配置
您可以配置一个 processor ,它可以校验并更新配置。
可以通过调用 setConfigurationProcessor
方法来实现。
处理过程绝对不能返回 null
。处理器获取到配置然后返回处理过的配置。
如果处理器不更新配置,它必须将输入的配置返回。
处理器可以抛出异常(例如,校验失败)。
以Future形式获取配置
ConfigRetriever
提供了一个
以 Future
形式接收配置的方式:
Future<JsonObject> future = retriever.getConfig();
future.onComplete(ar -> {
if (ar.failed()) {
// 获取配置失败
} else {
JsonObject config = ar.result();
}
});
扩展 Config Retriever
通过实现如下方式,您可以扩展配置:
-
ConfigProcessor
SPI 来增加对新格式的支持 -
ConfigStoreFactory
SPI来增加配置中心的支持(获取配置数据的位置)
其他格式
尽管Vert.x对于开箱即用的格式都提供了支持,但是 Vert.x Config 还是提供了额外的格式以供您的应用使用。
Hocon 配置格式
Hocon 配置格式扩展了 Vert.x Configuration Retriever 并提供了对 HOCON 格式 (https://github.com/typesafehub/config/blob/master/HOCON.md)的支持
它支持 json、properties、macros 等格式
使用 Hocon 配置格式
要使用Hocon配置格式, 添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-hocon</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-hocon:4.1.8'
指定配置中心以使用hocon
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个格式:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("file")
.setFormat("hocon")
.setConfig(new JsonObject()
.put("path", "my-config.conf")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
您必须将 format
设置为 hocon
。
Yaml 配置格式
Yaml 配置格式扩展了 Vert.x Configuration Retriever 并提供了对 Yaml格式 的支持
使用Yaml配置格式
要使用Yaml配置格式, 添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-yaml</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-yaml:4.1.8'
指定配置中心以使用yaml
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个格式:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("file")
.setFormat("yaml")
.setConfig(new JsonObject()
.put("path", "my-config.yaml")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
您必须将 format
设置为 yaml
。
其他配置中心
尽管Vert.x对于开箱即用的配置中心都提供了支持,但是 Vert.x Config 还是提供了额外的格式以供您的应用使用。
Git配置中心
git配置中心是对 Vert.x Configuration Retriever 的扩展, 用于从Git仓库获取配置。
使用git配置中心
要使用Git配置中心, 则添加如下依赖:
-
Maven(在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-git</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle(在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-git:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
以使用该配置中心:
ConfigStoreOptions git = new ConfigStoreOptions()
.setType("git")
.setConfig(new JsonObject()
.put("url", "https://github.com/cescoffier/vertx-config-test.git")
.put("path", "local")
.put("filesets",
new JsonArray().add(new JsonObject().put("pattern", "*.json"))));
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(git));
配置需要如下信息:
-
url
:git仓库的地址 -
path
:仓库被clone的路径(本地目录) -
user
:仓库的git用户名(默认不需要认证) -
password
: git用户的密码 -
idRsaKeyPath
:私有仓库所需的 ssh rsa 密钥 uri -
fileset
:指定要读取的文件集合 (与配置中心的目录配置意义相同)
您也可以配置要使用的分支( branch
参数,默认为 master
),
以及远程仓库名( remote
参数,默认为 origin
)
Kubernetes ConfigMap 配置中心
Kubernetes ConfigMap 配置中心扩展了 Vert.x Configuration Retriever 并提供了 对于 Kubernetes 的 ConfigMap 和 Secrets 的支持。 所以,配置是从 k8s 里的 configMap 或者 secret 对象中读取的。
使用 Kubernetes ConfigMap 配置中心
要使用 Kubernetes ConfigMap 配置中心, 则添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-kubernetes-configmap</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-kubernetes-configmap:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("configmap")
.setConfig(new JsonObject()
.put("namespace", "my-project-namespace")
.put("name", "configmap-name")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
您需要设置这个配置中心来找到正确的configMap。这通过如下配置项来解决:
-
namespace
- 项目的namespace,默认值为default
。如果设置了KUBERNETES_NAMESPACE
环境变量, 则会覆盖其值。 -
name
- configMap的名称 -
optional
- configMap是否是可选项(默认为true
)
如果configMap是由数个元素组成,您可以用 key
参数来告诉 Vert.x
来读取哪一个 key
。
Vert.x应用必须要有读取configMap的权限。
要从secret中读取数据,只需要将 secret
属性配置为 true
:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("configmap")
.setConfig(new JsonObject()
.put("namespace", "my-project-namespace")
.put("name", "my-secret")
.put("secret", true)
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
如果configMap访问不到,那么您会得到一个空的JSON object对象作为配置块。
要禁用这个行为并显式声明失败,您需要设置 optional
为 false
.
使用Redis配置中心
要使用Redis配置中心, 添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-redis</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-redis:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("redis")
.setConfig(new JsonObject()
.put("host", "localhost")
.put("port", 6379)
.put("key", "my-configuration")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
配置中心的配置用于创建 Redis
对象。
更多细节请查阅
Vert.x Redis Client 文档
另外,您可以设置 key
属性来指示配置中心中的某一 field ,
默认为 configuration
属性。
Redis客户端使用 HGETALL
配置项来获取配置。
Zookeeper配置中心
Zookeeper配置中心扩展了 Vert.x Configuration Retriever 并提供了从Zookeeper服务获取配置的方法。它使用 Apache Curator 作为客户端
使用zookeeper配置中心
要使用zookeeper配置中心, 添加如下依赖:
-
Maven (在您的
pom.xml
):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-zookeeper</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-zookeeper:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("zookeeper")
.setConfig(new JsonObject()
.put("connection", "localhost:2181")
.put("path", "/path/to/my/conf")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
这个配置用来配置 Apache Curator 客户端和包含配置的zookeeper节点的 路径 。 注意:配置的格式可以是JSON等任何Vert.x支持的格式。
这项配置必须需要 connection
属性指定zk服务的连接 字符串 (译者注:英文逗号隔开的多个zk服务节点),
以及 path
属性指定包含配置项的节点(znode)的路径。
您还可以额外配置:
-
maxRetries
:重连次数,默认3次。 -
baseSleepTimeBetweenRetries
:重试间隔毫秒值,默认1000毫秒。
Consul 配置中心
Consul配置中心扩展了 Vert.x Configuration Retriever , 并提供了从 Consul 获取配置的方法。
使用Consul配置中心
使用Consul配置中心, 需在您的项目构建配置中添加如下 依赖 :
-
Maven(在您的
pom.xml
文件中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-consul</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-consul:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
以使用该配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("consul")
.setConfig(new JsonObject()
.put("host", "localhost")
.put("port", 8500)
.put("prefix", "foo")
.put("raw-data", false)
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
这个配置用来创建
ConsulClient
对象。更多详细信息请查阅Vert.x Consul Client文档。
以下为设置 Consul 配置中心所需的参数:
prefix
-
构建配置树时需要被忽略的前缀,默认为空。
delimiter
-
用来分割Consul中的key的分隔符,用以维护配置树中的级别。默认为 "/"。
raw-data
-
如果
raw-data
为true
,则配置值不会进行类型转换,并且您可以用config.getString(key)
来获取原始数据,默认为true
。
Spring配置中心
Spring配置中心扩展了 Vert.x Configuration Retriever 并提供了从 Spring服务获取配置的方法。
使用Spring配置中心
要使用Spring配置中心, 则添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-spring-config-server</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-spring-config-server:4.1.8'
设置配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("spring-config-server")
.setConfig(new JsonObject().put("url", "http://localhost:8888/foo/development"));
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
可配置的属性如下:
-
url
- 获取配置的url
(强制必填),支持两种格式:-
/{application}/{environment}
,分别用不同的配置源来生成响应 -
/{application}-{environment}.json
,以具有唯一字段的JSON生成响应,并解析spring占位符
-
-
timeout
- 获取配置超时时间(毫秒),默认3000毫秒。 -
user
- 用户(默认无需认证) -
password
- 密码 -
httpClientConfiguration
- 底层HTTP客户端的配置
Vault配置中心
Vault配置中心扩展了 Vert.x Configuration Retriever 并提供了从 Vault (https://www.vaultproject.io/) 获取配置的方法。 所以,配置(即secrets)是从Vault获取的。
这个配置中心的 secrets 引擎是 Vault 的 Key/Value version 1 和 version 2 引擎( https://www.vaultproject.io/docs/secrets/kv/index.html )。暂不支持其他secrets引擎。
使用Vault配置中心
要使用Vault配置中心, 添加如下依赖:
-
Maven (在您的
pom.xml
文件):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-vault</artifactId>
<version>4.1.8</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.1.8</version>
</dependency>
-
Gradle (在您的
build.gradle
文件):
compile 'io.vertx:vertx-config:4.1.8'
compile 'io.vertx:vertx-config-vault:4.1.8'
指定配置中心
将该库加入classpath或者项目依赖后,您需要配置
ConfigRetriever
来使用这个配置中心:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
要使用Vault配置中心,则设置 type
为 vault
。其配置以JSON形式提供。
它配置了对Vault的访问权限、认证信息和secret路径:
JsonObject vault_config = new JsonObject()
.put("host", "127.0.0.1") // The host name
.put("port", 8200) // The port
.put("ssl", true); // 是否使用SSL (默认禁用)
// 认证
PemKeyCertOptions certs = new PemKeyCertOptions()
.addCertPath("target/vault/config/ssl/client-cert.pem")
.addKeyPath("target/vault/config/ssl/client-privatekey.pem");
vault_config.put("pemKeyCertOptions", certs.toJson());
// Truststore
JksOptions jks = new JksOptions()
.setPath("target/vault/config/ssl/truststore.jks");
vault_config.put("trustStoreOptions", jks.toJson());
// 读取secret的路径
vault_config.put("path", "secret/my-secret");
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));}
vault_config
对象可以包含 HTTP client / Web client 的配置,
例如 trust stores、timeout、certificates、port和host。 path
和 host
强制必填。
path
指定了需要获取的secret。 host
是Vault服务的hostname。默认情况下使用8200端口。
默认SSL关闭,但是生产环境下您需要开启它。
然后,您需要用如下中的一个方法来配置token或者认证机制。
使用已经存在的token
如果您已经得到了token,则在配置中设置 token
属性:
JsonObject vault_config = new JsonObject();
// ...
// 读取secret的路径
vault_config.put("path", "secret/my-secret");
// The token
vault_config.put("token", token);
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
您可以使用root token,但是不建议这样做。当token被回收,则对secret的访问也会受阻。 如果token可刷新,则当它过期的时候会被刷新。
生成token
如果您的token本身具有创建token的权限,您可以请求生成token:
JsonObject vault_config = new JsonObject();
// ...
// 读取secret的路径
vault_config.put("path", "secret/my-secret");
// 生成token的配置
// 配置token请求 (https://www.vaultproject.io/docs/auth/token.html)
JsonObject tokenRequest = new JsonObject()
.put("ttl", "1h")
.put("noDefault", true)
// (parts of the tokenRequest object) 用来做生成操作的token(tokenRequest object 的一部分)
.put("token", token);
vault_config.put("auth-backend", "token") // 指定所用的 auth backend
.put("renew-window", 5000L) // 更新误差容限(毫秒)
.put("token-request", tokenRequest); // 传入token生成的配置
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
当用这种方式,根配置中不必提供token,然后,用于生成token的token嵌于JSON数据被传入。
如果生成的token可刷新,那么在它过期的时候会自动刷新。
renew-window
是更新token有效性的时间窗口。
如果生成的token失效,则访问权限受阻。
使用证书
您可以使用TLS证书作为认证机制。所以,您不需要自己生成token, 它是自动生成的。
JsonObject vault_config = new JsonObject();
// ...
PemKeyCertOptions certs = new PemKeyCertOptions()
.addCertPath("target/vault/config/ssl/client-cert.pem")
.addKeyPath("target/vault/config/ssl/client-privatekey.pem");
vault_config.put("pemKeyCertOptions", certs.toJson());
PemTrustOptions trust = new PemTrustOptions()
.addCertPath("target/vault/config/ssl/cert.pem");
vault_config.put("pemTrustStoreOptions", trust.toJson());
JksOptions jks = new JksOptions()
.setPath("target/vault/config/ssl/truststore.jks");
vault_config.put("trustStoreOptions", jks.toJson());
vault_config.put("auth-backend", "cert");
// 读取secret的路径
vault_config.put("path", "secret/my-secret");
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
查看HTTP客户端和Web客户端的配置来传输证书。如果生成的token可刷新, 那么token会被刷新;如果不是,则配置中心会再次尝试认证。
使用 AppRole
当您的应用被Vault所知悉且您已经持有 appRoleId
和 secretId
, 此时会用到 AppRole
。
您不需要自己生成token,这个token会自动生成:
JsonObject vault_config = new JsonObject();
// ...
vault_config
.put("auth-backend", "approle") // Set the auth-backend to approle
.put("approle", new JsonObject() // Configure the role id and secret it
.put("role-id", appRoleId).put("secret-id", secretId)
);
// 读取secret的路径
vault_config.put("path", "secret/my-secret");
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
如果生成的token可刷新,那么他会被刷新;否则配置中心会再次尝试认证。
使用 username 和 password
user/app 在使用 username/password做认证的时候,会以 userpass
作为验证后台。
您并不需要自己生成token,因为认证过程中token已经生成:
JsonObject vault_config = new JsonObject();
// ...
vault_config
.put("auth-backend", "userpass") // 使用 userpass 作为验证后端
.put("user-credentials", new JsonObject()
.put("username", username).put("password", password)
);
// 读取secrete路径
vault_config.put("path", "secret/my-secret");
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("vault")
.setConfig(vault_config);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
如果生成的token可刷新,那么他会被刷新;否则配置中心会再次尝试认证。