Vert.x 配置

Vert.x 配置提供了一种配置 Vert.x 应用程序的方式。它

  • 提供多种配置语法(JSON、properties、Yaml(扩展)、Hocon(扩展)等)

  • 提供多种配置存储,例如文件、目录、HTTP、Git(扩展)、Redis(扩展)、系统属性和环境变量。

  • 允许您定义处理顺序和覆盖规则

  • 支持运行时重新配置

概念

该库围绕以下内容构建

配置检索器由 Vert.x 应用程序实例化和使用。它配置了一组配置存储 配置存储定义了读取配置数据的位置以及格式(默认为 JSON)

配置将作为 JSON 对象检索。

使用配置检索器

要使用配置检索器,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'

完成后,您首先需要实例化 ConfigRetriever

ConfigRetriever retriever = ConfigRetriever.create(vertx);

默认情况下,配置检索器会按以下顺序配置存储:

  • 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);

获得配置检索器实例后,按如下方式检索配置

retriever.getConfig().onComplete(ar -> {
  if (ar.failed()) {
    // Failed to retrieve the configuration
  } 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 服务器。

ConfigRetriever retriever = ConfigRetriever.create(vertx);
return retriever
  .getConfig()
  .compose(json -> vertx.createHttpServer()
    .requestHandler(req -> req.response().end(json.getString("message")))
    .listen(json.getInteger("port"))
  );

配置一组 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 实例。然后创建实际实例

Vertx vertx = Vertx.vertx();
// Create the config retriever
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
  .addStore(new ConfigStoreOptions().setType("file").setConfig(new JsonObject().put("path", "vertx.json"))));

// Retrieve the configuration
retriever.getConfig().onComplete(json -> {
  JsonObject result = json.result();
  // Close the vert.x instance, we don't need it anymore.
  vertx.close();

  // Create a new Vert.x instance using the retrieve configuration
  VertxOptions options = new VertxOptions(result);
  Vertx newVertx = Vertx.vertx(options);

  // Deploy your verticle
  newVertx.deployVerticle(GreetingVerticle.class.getName(), new DeploymentOptions().setConfig(result.getJsonObject("a")));
});

将配置更改传播到事件总线

当配置更改时,Vert.x Config 会通知您。如果您想对此事件做出反应,则需要自己实现反应逻辑。例如,您可以卸载并重新部署 verticle,或者将新配置发送到事件总线。以下示例展示了后一种情况。它将新配置发送到事件总线。感兴趣的 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);
});

可用的配置存储

配置检索器提供了一组配置存储和格式。更多内容可作为扩展提供,您也可以实现自己的。

配置结构

每个声明的数据存储都必须指定 type。它还可以定义 format。如果未设置,则使用 JSON。

某些配置存储需要额外的配置(例如路径等)。此配置作为 Json 对象通过 setConfig 传递

文件

此配置存储仅从文件读取配置。它支持所有受支持的格式。

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 对象。

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-datatrue,则不会尝试转换值,您可以使用 config.getString(key) 获取原始值。它在处理大整数时很有用。

如果要选择要导入的键集,请使用 keys 属性。它会过滤掉所有未选择的键。键必须单独列出

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-datatrue,则不会尝试转换值,您可以使用 config.getString(key) 获取原始值。它在处理大整数时很有用。

此外,还有 hierarchical 属性(默认为 false)。如果 hierarchicaltrue,系统属性将被解析为嵌套的 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 客户端(参见下一个代码片段)。为了简化配置,您还可以使用 hostportpath 属性配置 hostportpath。您还可以使用 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")
  );

此配置存储支持任何格式。

目录

此配置存储类似于 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 配置可以读取 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);
  }
});

监听配置更改

配置检索器会定期检索配置,如果结果与当前配置不同,您的应用程序可以重新配置。默认情况下,配置每 5 秒重新加载一次。

ConfigRetrieverOptions options = new ConfigRetrieverOptions()
  .setScanPeriod(2000)
  .addStore(store1)
  .addStore(store2);

ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.getConfig().onComplete(json -> {
  // Initial retrieval of the configuration
});

retriever.listen(change -> {
  // Previous configuration
  JsonObject previous = change.getPreviousConfiguration();
  // New configuration
  JsonObject conf = change.getNewConfiguration();
});

检索上次检索到的配置

您可以使用以下方式检索上次检索到的配置,而无需“等待”其被检索

JsonObject last = retriever.getCachedConfig();

以流形式读取配置

ConfigRetriever 提供了一种访问配置流的方式。它是一个 ReadStreamJsonObject。通过注册正确的一组处理程序,您会收到通知

  • 检索到新配置时

  • 检索配置时发生错误时

  • 配置检索器关闭时(调用 endHandler)。

ConfigRetrieverOptions options = new ConfigRetrieverOptions()
  .setScanPeriod(2000)
  .addStore(store1)
  .addStore(store2);

ConfigRetriever retriever = ConfigRetriever.create(Vertx.vertx(), options);
retriever.configStream()
  .endHandler(v -> {
    // retriever closed
  })
  .exceptionHandler(t -> {
    // an error has been caught while retrieving the configuration
  })
  .handler(conf -> {
    // the configuration
  });

处理配置

您可以配置一个处理器来验证和更新配置。这通过使用 setConfigurationProcessor 方法来完成。

处理不得返回 null。它获取检索到的配置并返回处理后的配置。如果处理器未更新配置,则必须返回输入配置。处理器可以抛出异常(例如用于验证目的)。

将配置作为 Future 检索

ConfigRetriever 提供了一种将配置作为 Future 检索的方法

Future<JsonObject> future = retriever.getConfig();
future.onComplete(ar -> {
  if (ar.failed()) {
    // Failed to retrieve the configuration
  } else {
    JsonObject config = ar.result();
  }
});

扩展配置检索器

您可以通过实现以下接口来扩展配置

附加格式

除了此库支持的开箱即用格式外,Vert.x Config 还提供了可在应用程序中使用的其他格式。

Hocon 配置格式

Hocon 配置格式扩展了 Vert.x 配置检索器,并提供对 HOCON 格式的支持。

它支持包含、json、properties、宏等。

使用 Hocon 配置格式

要使用 Hocon 配置格式,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-hocon</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-hocon:5.0.1'

配置存储以使用 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

使用系统环境变量覆盖配置

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 配置格式

Yaml 配置格式扩展了 Vert.x 配置检索器,并提供对 Yaml 配置格式的支持。

使用 Yaml 配置格式

要使用 Yaml 配置格式,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-yaml</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-yaml:5.0.1'

配置存储以使用 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 Config 还提供了可在应用程序中使用的其他存储。

Git 配置存储

Git 配置存储是 Vert.x 配置检索器的扩展,用于从 Git 仓库检索配置。

使用 Git 配置存储

要使用 Git 配置,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-git</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-git:5.0.1'

配置存储

添加到 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

  • 仓库克隆到的 path(本地目录)

  • 私有仓库的 user(默认无认证)

  • 用户的 password

  • 私有仓库的 idRsaKeyPath 并且需要 SSH URI

  • 至少一个 fileset 指示要读取的文件集(与目录配置存储行为相同)。

您还可以配置要使用的 branch(默认为 master)以及 remote 仓库的名称(默认为 origin)。

工作原理

如果本地 path 不存在,配置存储会将仓库克隆到此目录。然后它会读取与不同文件集匹配的文件。

如果本地 path 存在,它会尝试更新(如果需要,会切换分支)。如果更新失败,配置检索也会失败。

仓库会定期更新,以检查配置是否已更新。

Kubernetes ConfigMap 存储

Kubernetes ConfigMap 存储扩展了 Vert.x 配置检索器,并提供对 Kubernetes Config Map 和 Secrets 的支持。因此,通过读取 config map 或 secrets 来检索配置。

使用 Kubernetes ConfigMap 存储

要使用 Kubernetes ConfigMap 存储,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-kubernetes-configmap</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-kubernetes-configmap:5.0.1'

配置存储

添加到 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 - 项目命名空间,默认为 default。如果设置了 KUBERNETES_NAMESPACE 环境变量,它将使用此值。

  • name - config map 的名称

  • optional - config map 是否可选(默认为 true

如果 config map 由多个元素组成,您可以使用 key 参数来指定读取哪个 key

应用程序必须具有读取 config map 的权限。

要从 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));

如果 config map 不可用,则将空 JSON 对象作为配置块传递。要禁用此行为并显式失败,您可以将 optional 配置设置为 false

Redis 配置存储

Redis 配置存储扩展了 Vert.x 配置检索器,并提供从 Redis 服务器检索配置的方式。

使用 Redis 配置存储

要使用 Redis 配置存储,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-redis</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-redis:5.0.1'

配置存储

添加到 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 客户端的文档。

此外,您可以设置 key 指示存储在哪个 字段 中存储配置。configuration 默认使用。

创建的 Redis 客户端使用 HGETALL 配置检索配置。

Zookeeper 配置存储

Zookeeper 配置存储扩展了 Vert.x 配置检索器,并提供从 Zookeeper 服务器检索配置的方式。它使用 Apache Curator 作为客户端。

使用 Zookeeper 配置存储

要使用 Redis 配置存储,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-zookeeper</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-zookeeper:5.0.1'

配置存储

添加到 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 或任何受支持的格式。

配置需要 connection 属性,指示 Zookeeper 服务器的连接 字符串,以及 path 属性,指示包含配置的节点的路径。

此外,您可以配置

  • maxRetries: 连接尝试次数,默认为 3

  • baseSleepTimeBetweenRetries: 两次重试之间等待的毫秒数(指数退避策略)。默认为 1000 毫秒。

Consul 配置存储

Consul 配置存储扩展了 Vert.x 配置检索器,并提供了从 Consul 检索配置的方式。

使用 Consul 配置存储

要使用 Consul 配置存储,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-consul</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-consul:5.0.1'

配置存储

添加到 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 客户端的文档。以下是 Consul 配置存储特有的参数

prefix(前缀)

构建配置树时不会考虑的前缀。默认为空。

delimiter(分隔符)

用于在 Consul 存储中拆分键以获取配置树中级别的符号。默认为“/”。

raw-data(原始数据)

如果 raw-datatrue,则不会尝试转换值,您可以使用 config.getString(key) 获取原始值。默认为 true。

Spring Config Server 存储

Spring Config Server 存储扩展了 Vert.x 配置检索器,并提供了一种从 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>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-spring-config-server:5.0.1'

配置存储

添加到 classpath 或依赖项后,您需要配置 ConfigRetriever 以使用此存储

ConfigStoreOptions store = new ConfigStoreOptions()
    .setType("spring-config-server")
    .setConfig(new JsonObject().put("url", "https://:8888/foo/development"));

ConfigRetriever retriever = ConfigRetriever.create(vertx,
    new ConfigRetrieverOptions().addStore(store));

可配置的属性有

  • url - 检索配置的 url(强制),支持两种格式

    • /{application}/{environment} 生成带有单独 propertySources 的响应

    • /{application}-{environment}.json 生成带有唯一字段和已解析 Spring 占位符的 JSON 响应

  • timeout - 检索配置的超时时间(毫秒),默认为 3000

  • user - 用户 user(默认无认证)

  • password - 密码

  • httpClientConfiguration - 底层 HTTP 客户端的配置

Vault 配置存储

Vault 存储扩展了 Vert.x 配置检索器,并提供对 Vault (https://www.vaultproject.io/) 的支持。因此,配置(secrets)是从 Vault 中检索的。

此存储支持的 secrets 引擎是 Vault Key/Value 版本 1 和版本 2 引擎 (https://www.vaultproject.io/docs/secrets/kv/index.html)。不支持其他 secrets 引擎。

使用 Vault 配置存储

要使用 Vault 配置存储,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config-vault</artifactId>
  <version>5.0.1</version>
</dependency>
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-config</artifactId>
  <version>5.0.1</version>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

compile 'io.vertx:vertx-config:5.0.1'
compile 'io.vertx:vertx-config-vault:5.0.1'

配置存储

添加到 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); // Whether or not SSL is used (disabled by default)

// Certificates
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());

// Path to the secret to read.
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 客户端配置,例如信任存储、超时、证书、端口和主机。pathhost 条目是强制性的。path 指示要检索的 secret。host 是 Vault 服务器的主机名。默认使用端口 8200。SSL 默认禁用,但生产环境应启用它。

然后,您需要使用以下方法之一来配置要使用的令牌或认证机制。

使用现有令牌

如果您知道要使用的令牌,请在配置中设置 token 条目

JsonObject vault_config = new JsonObject();

// ...

// Path to the secret to read.
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 令牌,但它不推荐。当令牌被吊销时,对 secret 的访问将被阻止。如果令牌可续订,则在到期时续订令牌。

生成令牌

如果您有一个允许生成新令牌的令牌,您可以请求生成令牌

JsonObject vault_config = new JsonObject();

// ...

// Path to the secret to read.
vault_config.put("path", "secret/my-secret");

// Configure the token generation

// Configure the token request (https://www.vaultproject.io/docs/auth/token.html)
JsonObject tokenRequest = new JsonObject()
  .put("ttl", "1h")
  .put("noDefault", true)

  // The token to use to request the generation (parts of the tokenRequest object)
  .put("token", token);

vault_config.put("auth-backend", "token") // Indicate the auth backend to use
  .put("renew-window", 5000L) // Renew error margin in ms
  .put("token-request", tokenRequest); // Pass the token generation configuration

ConfigStoreOptions store = new ConfigStoreOptions()
  .setType("vault")
  .setConfig(vault_config);

ConfigRetriever retriever = ConfigRetriever.create(vertx,
  new ConfigRetrieverOptions().addStore(store));

使用此方法时,根配置中无需提供令牌,用于请求生成的令牌将在嵌套 JSON 结构中传递。如果生成的令牌可续订,它将在到期时自动续订。renew-window 是添加到令牌有效期以续订令牌的时间窗口。如果生成的令牌被吊销,则对 secret 的访问将被阻止。

使用证书

您可以使用 TLS 证书作为认证机制。因此,您不需要知道令牌,令牌是自动生成的。

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");

// Path to the secret to read.
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 客户端配置以传递证书。如果生成的令牌可续订,它将续订。如果不可续订,存储将再次尝试认证。

使用 AppRole

当您的应用程序被 Vault 识别并且您拥有 appRoleIdsecretId 时,会使用 AppRole。您不需要令牌,令牌是自动生成的

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)
  );

// Path to the secret to read.
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));

如果生成的令牌可续订,它将续订。如果不可续订,存储将再次尝试认证。

使用用户名和密码

当用户/应用程序使用用户名/密码进行认证时,会使用 userpass 认证后端。您不需要令牌,因为令牌是在认证过程中生成的

JsonObject vault_config = new JsonObject();

// ...

vault_config
  .put("auth-backend", "userpass") // Set the auth-backend to userpass
  .put("user-credentials", new JsonObject()
    .put("username", username).put("password", password)
  );

// Path to the secret to read.
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));

如果生成的令牌可续订,它将续订。如果不可续订,存储将再次尝试认证。