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.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

以上工作完成之后,您第一件要做的事情就是实例化 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();
});

获取上一次的配置

您可以获取上一次获取到的配置而不用 "等到" 被获取的时候。 这需要用如下方式实现:

JsonObject last = retriever.getCachedConfig();

以流的方式读取配置

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

通过实现如下方式,您可以扩展配置:

其他格式

尽管Vert.x对于开箱即用的格式都提供了支持,但是 Vert.x Config 还是提供了额外的格式以供您的应用使用。

Hocon 配置格式

Hocon 配置格式扩展了 Vert.x Configuration Retriever 并提供了对 HOCON 格式 HOCON 的支持

它支持 json、properties、macros 等格式

使用 Hocon 配置格式

要使用Hocon配置格式, 添加如下依赖:

  • Maven (在您的 pom.xml 文件):

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

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

指定配置中心以使用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 。

You just need to set format to hocon.

Override configuration using system environment variables

Hocon supports system environment variable overrides using keys with CONFIG_FORCE_ prefix. You can use this feature by specifying hocon.env.override to true in the configuration:

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 Configuration Retriever 并提供了对 Yaml格式 的支持

使用Yaml配置格式

要使用Yaml配置格式, 添加如下依赖:

  • Maven (在您的 pom.xml 文件):

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

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

指定配置中心以使用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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle(在您的 build.gradle 文件):

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

设置配置中心

将该库加入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 )

如何工作

如果本地的仓库目录(由 path 参数指定)不存在,那么配置中心会 clone 远程仓库到这个本地目录。 然后它会读取符合 fileset 配置的文件。

如果本地的仓库目录(由 path 参数指定)存在,它会尝试更新(按需切换分支)。 如果更新失败,则视为获取配置失败。

配置中心会周期性更新 git 仓库来检查配置是否更新。

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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

设置配置中心

将该库加入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配置中心

Reids配置中心扩展了 Vert.x Configuration Retriever 并提供了从Redis服务获取配置的方法。

使用Redis配置中心

要使用Redis配置中心, 添加如下依赖:

  • Maven (在您的 pom.xml 文件):

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

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

设置配置中心

将该库加入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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

设置配置中心

将该库加入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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

设置配置中心

将该库加入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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

设置配置中心

将该库加入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.4.0</version>
</dependency>
<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-config</artifactId>
 <version>4.4.0</version>
</dependency>
  • Gradle (在您的 build.gradle 文件):

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

指定配置中心

将该库加入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可刷新,那么他会被刷新;否则配置中心会再次尝试认证。