Vert.x 的 Verticle(s) JSON/YAML 配置(每个环境最好)

Vert.x's Verticle(s) JSON/YAML configuration (preferable per environment)

在Vert.x中是否有"reasonable"配置deployment optionsinstancesworker等的方法?

我希望能够在部署时 "get rid" of DeploymentOptions 并将其放在 JSON/YAML 配置文件中 Vert.x 以某种方式理解 - 最好按 "environments",与 Spring Boot 的方式相同。

这是我目前使用的:

class MainVerticle : AbstractVerticle() {
  private val logger: Logger = LoggerFactory.getLogger(this.javaClass.name)

  override fun start(future: Future<Void>) {
    val config = config().getJsonObject("verticle_instances")
    deploy(AuthVerticle::class.java, DeploymentOptions().setInstances(config.getInteger("auth_instances")))
    deploy(HttpServerVerticle::class.java, DeploymentOptions().setConfig(config().getJsonObject("http_server_verticle"))
        .setInstances(config.getInteger("http_server_instances")))
    deploy(DialPadVerticle::class.java, DeploymentOptions().setConfig(config().getJsonObject("phone_verticle"))
        .setWorker(true))
    logger.info("Module(s) and/or verticle(s) deployment...DONE")
    future.complete()
  }

  override fun stop(future: Future<Void>) {
    logger.debug("Undeploying verticle(s)...DONE")
    logger.info("Application stopped successfully. Enjoy the elevator music while we're offline...")
    future.complete()
  }

  private fun deploy(clazz: Class<out AbstractVerticle>, options: DeploymentOptions) {
    vertx.deployVerticle(clazz.name, options) { handler ->
      if (handler.succeeded()) {
        logger.debug("${clazz.simpleName} started successfully (deployment identifier: ${handler.result()})")
      } else {
        logger.error("${clazz.simpleName} deployment failed due to: ${handler.cause()}")
        //stop();
      }
    }
  }
}

...和config.json:

{
  "verticle_instances": {
    "auth_instances": 3,
    "http_server_instances": 6
  },
  "http_server_verticle": {
    "hostname": "0.0.0.0",
    "port": 9080,
    "cert_path": "server-cert.pem",
    "key_path": "server-key.pem",
    "use_alpn": true,
    "use_ssl": true
  }
}

据我所知,没有。但是,您可以对 config.jsondeploy(Class, DeploymentOptions) 方法进行一些调整以获得类似的结果。

对于 config.json,如果您将每个 Verticle 的名称更改为合格的 class 名称并且每个 Verticle 都有一个 deployment_options 对象,那么您可以修改 deploy() 加载选项而无需在 start 方法中指定它们。在 Vert.x 中,您可以提供默认配置选项,因此您可以执行以下操作:

override fun start(future: Future<Void>) {
    deploy(AuthVerticle::class.java)
    deploy(HttpServerVerticle::class.java)
    deploy(DialPadVerticle::class.java)
    ...
}

private fun deploy(clazz: Class<out AbstractVerticle>) {
    val options = getDeploymentOptionsFromConfig(clazz)
    vertx.deployVerticle(clazz.name, options) { handler ->
        ...
    }
}

private fun getDeploymentOptionsFromConfig(clazz: Class<out AbstractVerticle>): DeploymentOptions {
    val config = config()
            .getJsonObject(clazz.name)
            .getJsonObject("deployment_options")

    return DeploymentOptions()
            .setInstances(config.getInteger("instances", 1))
            .setWorker(config.getBoolean("worker", false))
}

我找到了 Vert.x Config Launcher,但我仍然认为这应该是一个 "core" 功能。

无论如何,DeploymentOptions 接受 JsonObject...这很好。唯一需要注意的是确保 JSON 配置文件中的键(当然不包括 config 中的键)与方法 fromJson 中的值相同(DeploymentOptionsConverter) 是 "expecting".

"partial" 解决方案是 config.json 如:

{
  "io.shido.core.verticle.AuthVerticle": { },
  "io.shido.core.verticle.DialPadVerticle": { },
  "io.shido.core.verticle.HttpServerVerticle": {
    "config": {
      "hostname": "0.0.0.0",
      "port": 9081,
      "certPath": "server-cert.pem",
      "keyPath": "server-key.pem",
      "useAlpn": true,
      "useSsl": true
    },
    "instances": 5
  }
}

...非常类似于 foreksorg/vertx-config-launcher 所做的子集——因为我只对 配置注入 部分感兴趣。

最终,(最初发布的)deploy 方法将如下所示:

private fun deploy(clazz: Class<out AbstractVerticle>) {
  vertx.deployVerticle(clazz.name, DeploymentOptions(config().getJsonObject(clazz.name) ?: JsonObject())) { handler ->
    if (handler.succeeded()) {
      logger.debug("${clazz.simpleName} started successfully (deployment identifier: ${handler.result()})")
    } else {
      logger.error("${clazz.simpleName} deployment failed due to: ${handler.cause()}")
      //stop();
    }
  }
}