<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
Vert.x 配置中心(Config)
Vert.x Config 提供了配置 Vert.x 应用程序的途径。 它:
-
支持多种配置语法(JSON、Properties、YAML(扩展)、HOCON(扩展)等)
-
支持多种配置存储,如文件、目录、HTTP、Git(扩展)、Redis(扩展)、系统属性以及环境变量
-
允许你定义处理顺序和覆盖规则
-
支持运行时动态重新配置
核心概念
该库主要围绕以下概念构建:
Config Retriever(配置检索器) 由 Vert.x 应用程序实例化并使用。它配置了一组配置存储(Configuration Store)。 Configuration Store(配置存储) 定义了读取配置数据的位置以及格式(默认为 JSON)。
配置最终作为 JSON 对象获取。
使用 Config Retriever
要使用 Config Retriever,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
添加依赖后,你首先需要实例化 ConfigRetriever:
ConfigRetriever retriever = ConfigRetriever.create(vertx);
默认情况下,Config Retriever 配置了以下存储(按此顺序):
-
Vert.x Verticle 的
config() -
系统属性(System Properties)
-
环境变量(Environment Variables)
-
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().onComplete(ar -> {
if (ar.failed()) {
// 获取配置失败
} else {
JsonObject config = ar.result();
}
});
覆盖规则
配置存储的声明顺序非常重要,因为它定义了覆盖关系。对于冲突的键,最后声明的配置存储会覆盖先前配置存储提供的值。举个例子,我们有两个配置存储:
-
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}。
使用获取到的配置
获取到的配置可用于:
-
配置 Verticle
-
配置端口、客户端、地址等
-
配置 Vert.x 自身
本节给出一些使用示例。
配置单个 Verticle
以下示例可以放置在 Verticle 的 start 方法中。它检索配置(使用默认存储),并使用配置内容来配置 HTTP 服务端。
`link:../../apidocs/io/vertx/core/AbstractVerticle.html#start--[start]`
配置一组 Verticle
以下示例使用 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().onComplete(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();
// 创建配置检索器
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "vertx.json"))));
// 检索配置
retriever.getConfig().onComplete(json -> {
JsonObject result = json.result();
// 关闭临时 Vert.x 实例,我们不再需要它。
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")));
});
将配置变更传播到 Event Bus
Vert.x Config 会在配置发生变更时通知你。如果你希望响应此事件,需要自行实现响应逻辑。例如,你可以取消部署并重新部署 Verticle,或者在 Event Bus 上发送新配置。以下示例展示了后一种情况:它在 Event Bus 上广播新配置,感兴趣的 Verticle 可以监听此地址并自行更新:
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "verticles.json"))));
retriever.getConfig().onComplete(json -> {
//...
});
retriever.listen(change -> {
JsonObject json = change.getNewConfiguration();
vertx.eventBus().publish("new-configuration", json);
});
支持的配置存储(Configuration Store)
Config Retriever 提供了多种开箱即用的配置存储和格式。 更多配置存储和格式以扩展的形式提供,你也可以实现自己的存储。
配置结构
每个声明的数据存储都必须指定 type。它也可以定义 format;如果未指定,默认使用 JSON。
某些配置存储需要额外的配置(例如文件路径等)。该配置通过 setConfig 以 JSON 对象的形式传入。
文件(File)
此配置存储直接从文件中读取配置。它支持所有支持的格式。
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。
环境变量(Environment Variables)
此配置存储将环境变量转换为 JSON 对象,并合并到全局配置中。
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) 获取原始值。这在处理大整数时非常有用。
如果你想指定导入的键集合,可以使用 keys 属性。它会过滤掉所有未选中的键。键必须逐个列出:
ConfigStoreOptions env = new ConfigStoreOptions()
.setType("env")
.setConfig(new JsonObject().put("keys", new JsonArray().add("SERVICE1_HOST").add("SERVICE2_HOST")));
系统属性(System Properties)
此配置存储将系统属性转换为 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")));
Event Bus
此 Event Bus 配置存储从 Event Bus 接收配置。该存储允许你在本地和分布式组件之间分发配置。
ConfigStoreOptions eb = new ConfigStoreOptions()
.setType("event-bus")
.setConfig(new JsonObject()
.put("address", "address-getting-the-conf")
);
此配置存储支持任意格式。
目录(Directory)
此配置存储与 file 配置存储类似,但它不是读取单个文件,而是从目录中读取多个文件。
此配置存储的配置需要:
-
path- 文件所在的根目录 -
至少一个
fileset- 用于选择文件的对象 -
对于 Properties 文件,你可以使用
raw-data属性指示是否要禁用类型转换
每个 fileset 包含:
-
pattern:用于选择文件的 Ant 风格模式。该模式应用于相对于当前工作目录的文件相对路径。 -
可选的
format,用于指示文件的格式(每个 fileset 可以使用不同的格式,但是同一个 fileset 中的文件必须具有相同的格式)。
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);
}
});
监听配置变更
Config Retriever 会定期获取配置,如果获取的结果与当前配置不同,你的应用程序可以重新进行配置。默认情况下,配置每 5 秒重新加载一次。
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.setScanPeriod(2000)
.addStore(store1)
.addStore(store2);
ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.getConfig().onComplete(json -> {
// 初次检索配置
});
retriever.listen(change -> {
// 上一次配置
JsonObject previous = change.getPreviousConfiguration();
// 新配置
JsonObject conf = change.getNewConfiguration();
});
获取上一次检索的配置
你可以无需“等待”检索即可获取上一次检索到的配置,方法如下:
JsonObject last = retriever.getCachedConfig();
以流(Stream)的形式读取配置
ConfigRetriever 提供了访问配置流的途径。
它是一个以 JsonObject 为数据项的 ReadStream。通过注册相应的处理器,你可以在以下时机收到通知:
-
检索到新配置时
-
检索配置发生错误时
-
配置检索器关闭时(调用
endHandler)
ConfigRetrieverOptions options = new ConfigRetrieverOptions()
.setScanPeriod(2000)
.addStore(store1)
.addStore(store2);
ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.configStream()
.endHandler(v -> {
// 检索器已关闭
})
.exceptionHandler(t -> {
// 检索配置时捕获到错误
})
.handler(conf -> {
// 获取到的配置
});
处理配置(Processing Configuration)
你可以配置一个处理器(Processor)来验证和更新配置。这可以通过 setConfigurationProcessor 方法实现。
处理方法不得返回 null。它接收检索到的配置并返回处理后的配置。如果处理器未更新配置,则必须返回输入的配置。处理器也可以抛出异常(例如用于校验目的)。
以 Future 形式获取配置
ConfigRetriever 提供了将配置作为 Future 检索的方法:
Future<JsonObject> future = retriever.getConfig();
future.onComplete(ar -> {
if (ar.failed()) {
// 获取配置失败
} else {
JsonObject config = ar.result();
}
});
扩展 Config Retriever
你可以通过实现以下接口来扩展配置功能:
-
ConfigProcessorSPI:添加对某种格式的支持 -
ConfigStoreFactorySPI:添加对配置存储的支持(从何处获取配置数据)
扩展配置格式
除了该库开箱即用支持的格式之外,Vert.x Config 还提供了可在应用程序中使用的扩展格式。
HOCON 配置格式(Configuration Format)
HOCON 配置格式对 Vert.x Configuration Retriever 进行了扩展,提供了对 HOCON 格式的支持。
它支持 include 包含、JSON、Properties 以及宏等特性。
使用 HOCON 配置格式
要使用 HOCON 配置格式,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-hocon</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-hocon:4.5.35'
配置存储以使用 HOCON
将其添加到类路径或依赖后,你需要配置 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 即可。
使用系统环境变量覆盖配置
HOCON 支持通过带有 CONFIG_FORCE_ 前缀的键来实现 系统环境变量覆盖。你可以在配置中将 hocon.env.override 指定为 true 来启用此特性:
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("file")
.setFormat("hocon")
.setConfig(new JsonObject()
.put("hocon.env.override", true)
.put("path", "my-config.conf")
);
ConfigRetriever retriever = ConfigRetriever.create(vertx,
new ConfigRetrieverOptions().addStore(store));
YAML 配置格式(Configuration Format)
YAML 配置格式对 Vert.x Configuration Retriever 进行了扩展,提供了对 YAML 配置格式的支持。
使用 YAML 配置格式
要使用 YAML 配置格式,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-yaml</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-yaml:4.5.35'
配置存储以使用 YAML
将其添加到类路径或依赖后,你需要配置 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 Config 还提供了可在应用程序中使用的扩展存储。
Git 配置存储(Configuration Store)
Git 配置存储是 Vert.x Configuration Retriever 的一个扩展,用于从 Git 仓库中获取配置。
使用 Git 配置存储
要使用 Git 配置存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-git</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-git:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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 -
仓库克隆的
path(本地目录) -
用于私有仓库的
user(默认无认证) -
用户的
password -
用于私有仓库且需要 SSH URI 时的
idRsaKeyPath -
至少一个指示要读取的文件集的
fileset(其行为与目录配置存储相同)。
你还可以配置要使用的 branch(默认为 master)以及 remote 远程仓库名称(默认为 origin)。
工作原理
若本地 path 不存在,配置存储会将仓库克隆到该目录中。然后读取匹配不同文件集的文件。
若本地 path 已存在,它会尝试更新该目录(必要时会切换分支)。如果更新失败,则配置获取失败。
配置存储会定期更新仓库,以检查配置是否有更新。
Kubernetes ConfigMap 存储
Kubernetes ConfigMap 存储对 Vert.x Configuration Retriever 进行了扩展,提供了对 Kubernetes ConfigMap 和 Secret 的支持。因此,可以通过读取 ConfigMap 或 Secret 来获取配置。
使用 Kubernetes ConfigMap 存储
要使用 Kubernetes ConfigMap 存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-kubernetes-configmap</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-kubernetes-configmap:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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- 项目命名空间,默认为default。如果设置了KUBERNETES_NAMESPACE环境变量,则会优先使用该值。 -
name- ConfigMap 的名称 -
optional- 该 ConfigMap 是否是可选的(默认为true)
如果 ConfigMap 由多个元素组成,你可以使用 key 参数指定要读取哪一个 key。
应用程序必须具备读取该 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 对象作为配置块。若要禁用此默认行为并使其显式失败,可以将 optional 配置设置为 false。
Redis 配置存储(Configuration Store)
Redis 配置存储对 Vert.x Configuration Retriever 进行了扩展,提供了从 Redis 服务器检索配置的方法。
使用 Redis 配置存储
要使用 Redis 配置存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-redis</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-redis:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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,指示该存储将配置保存在哪个键/字段中。默认使用 configuration。
创建的 Redis 客户端使用 HGETALL 命令来获取配置。
ZooKeeper 配置存储(Configuration Store)
ZooKeeper 配置存储对 Vert.x Configuration Retriever 进行了扩展,提供了从 ZooKeeper 服务器检索配置的方法。它使用 Apache Curator 作为客户端。
使用 ZooKeeper 配置存储
要使用 ZooKeeper 配置存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-zookeeper</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-zookeeper:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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 节点 path。请注意,配置格式可以是 JSON,也可以是任何受支持的格式。
该配置需要提供指示 ZooKeeper 服务器连接字符串的 connection 属性,以及指示包含该配置的节点路径的 path 属性。
此外,你还可以配置:
-
maxRetries:连接尝试次数,默认为 3 -
baseSleepTimeBetweenRetries:重试之间的等待毫秒数(指数退避策略),默认为 1000 毫秒。
Consul 配置存储(Configuration Store)
Consul 配置存储对 Vert.x Configuration Retriever 进行了扩展,提供了从 Consul 获取配置的能力。
使用 Consul 配置存储
要使用 Consul 配置存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-consul</artifactId>
<version>5.0.12</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>5.0.12</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:5.0.12'
compile 'io.vertx:vertx-config-consul:5.0.12'
配置该存储
将其添加到类路径或依赖后,你需要配置 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 存储中的键以生成配置树层级结构的符号。默认为 "/"。
raw-data-
若
raw-data为true,则不会尝试转换值,你可以使用config.getString(key)获取原始值。默认为 true。
Spring Config Server 存储
Spring Config Server 存储对 Vert.x Configuration Retriever 进行了扩展,提供了从 Spring Server 检索配置的方法。
使用 Spring Config Server 存储
要使用 Spring Config Server 存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-spring-config-server</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-spring-config-server:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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}:返回包含独立 propertySources 的响应 -
/{application}-{environment}.json:以 JSON 格式返回响应,包含唯一定义的字段并已解析 Spring 占位符
-
-
timeout- 检索配置的超时时间(毫秒),默认为 3000 -
user- 用户名user(默认无认证) -
password- 密码password -
httpClientConfiguration- 底层 HTTP 客户端的配置
Vault 配置存储(Config Store)
Vault 存储对 Vert.x Configuration Retriever 进行了扩展,提供了对 Vault (https://www.vaultproject.io/) 的支持。 因此,可以从 Vault 中检索配置(Secret)。
该存储支持的机密引擎为 Vault 键/值(Key/Value)版本 1 和版本 2 引擎(https://www.vaultproject.io/docs/secrets/kv/index.html)。不支持其他机密引擎。
使用 Vault 配置存储
要使用 Vault 配置存储,请将以下依赖添加到构建描述文件的 dependencies 节点中:
-
Maven(在你的
pom.xml中):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-vault</artifactId>
<version>4.5.35</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
<version>4.5.35</version>
</dependency>
-
Gradle(在你的
build.gradle文件中):
compile 'io.vertx:vertx-config:4.5.35'
compile 'io.vertx:vertx-config-vault:4.5.35'
配置该存储
将其添加到类路径或依赖后,你需要配置 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") // 主机名
.put("port", 8200) // 端口
.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());
// 信任库
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 客户端 / Web 客户端配置,例如信任库、超时、证书、端口和主机。path 和 host 项为必填项。path 指示要检索的 secret。host 为 Vault 服务器的主机名。默认端口为 8200。默认禁用 SSL,但在生产环境中建议启用它。
接下来,你需要使用以下方法之一来配置所使用的 Token 或认证机制。
使用现有 Token
如果你已知所使用的 Token,请在配置中设置 token 项:
JsonObject vault_config = new JsonObject();
// ...
// 要读取的 secret 路径。
vault_config.put("path", "secret/my-secret");
// 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)
// 用于请求生成的 Token(tokenRequest 对象的一部分)
.put("token", token);
vault_config.put("auth-backend", "token") // 指示使用的认证后端
.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 需在嵌套的 JSON 结构中传递。如果生成的 Token 是可续期的,它将在到期时自动续期。renew-window 是添加到 Token 有效期中用于提前续期的时间窗口。如果生成的 Token 被吊销,对该 secret 的访问将被阻止。
使用证书
你可以使用 TLS 证书作为认证机制。这样你无需预先知晓 Token,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 是可续期的,它将被自动续期。如果不可续期,该存储将尝试重新认证。
使用 AppRole
当你的应用程序已被 Vault 登记并且你拥有 appRoleId 和 secretId 时,可以使用 AppRole。你无需手动提供 Token,Token 会自动生成:
JsonObject vault_config = new JsonObject();
// ...
vault_config
.put("auth-backend", "approle") // 将 auth-backend 设置为 approle
.put("approle", new JsonObject() // 配置 role id 和 secret id
.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 是可续期的,它将被自动续期。如果不可续期,该存储将尝试重新认证。
使用用户名和密码
当用户或应用程序使用用户名/密码进行认证时,可使用 userpass 认证后端。你无需预先提供 Token,因为在认证过程中会自动生成 Token:
JsonObject vault_config = new JsonObject();
// ...
vault_config
.put("auth-backend", "userpass") // 将 auth-backend 设置为 userpass
.put("user-credentials", new JsonObject()
.put("username", username).put("password", password)
);
// 要读取的 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 是可续期的,它将被自动续期。如果不可续期,该存储将尝试重新认证。