Vert.x 应用的配置

在上篇文章中,开发了一个简单的Vert.x应用,介绍了怎么测试,打包和执行,这仅仅是一个开始,在这篇文章中,我们通过配置来提高应用。

还记得,在上一个应用中有HTTP server,监听8080端口,应答一个“Hello”的消息,上篇文章的代码在这里,本篇文章的代码在github

为什么需要配置?

这个问题非常好。这个应用是正常工作的,但是如果当你部署在8080端口已经被占领了的机器上,如果要部署在这个机器上,我们就需要到代码里修改应用程序和测试里的端口了,这不能忍受,很幸运的是Vert.x配置一下就可以了。

Vert.x使用的是JSON格式配置的,所以很简单,可以使用API传给verticle或者命令行,我们来看一看。

不使用 ‘8080’ 端口

第一步是修改name/quanke/study/vertx/first/MyFirstVerticle.java类,从配置里读取端口,而不8080绑定,默认是8080端口:

public void start(Future<Void> fut) {
  vertx
      .createHttpServer()
      .requestHandler(r -> {
        r.response().end("Hello from my first " +
            "Vert.x 3 application");
      })
      .listen(
          // Retrieve the port from the configuration,
          //从配置里检索端口
          // default to 8080.
          //默认8080
          config().getInteger("http.port", 8080),
          result -> {
            if (result.succeeded()) {
              fut.complete();
            } else {
              fut.fail(result.cause());
            }
          }
      );
}

与上一版本的区别仅仅是listen里面的第一个参数8080换成config().getInteger("http.port", 8080)。这里,我们的代码会请求这个配置并检查http.port属性是否配置了。如果没有,将会默认使用8080端口。配置信息是从JsonObject中返回的。

默认还是使用8080,所以打包运行和以前一样:

mvn clean package
java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

使用API的方式配置 - 在测试中随机生成端口号

在测试代码中,我们把端口修改成8081,部署(deploying)verticle的代码如下:

vertx.deployVerticle(MyFirstVerticle.class.getName(), context.asyncAssertSuccess());

传入部署(deploying)选项:

port = 8081;
DeploymentOptions options = new DeploymentOptions()
    .setConfig(new JsonObject().put("http.port", port)
);
vertx.deployVerticle(MyFirstVerticle.class.getName(), options, context.asyncAssertSuccess());

post在全局变量里面声明的private Integer port;

DeploymentOptions对象可以定义多个参数。将JsonObject注入到verticle的config()方法中。

连接服务器的代码需要修改一下,端口要和测试里面的一样才行。

vertx.createHttpClient().getNow(port, "localhost", "/", response -> {
  response.handler(body -> {
    context.assertTrue(body.toString().contains("Hello"));
    async.complete();
  });
});

这个并没有完全解决问题,如果8081端口也被占用了怎么办?我们使用随机端口:

ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();

DeploymentOptions options = new DeploymentOptions()
    .setConfig(new JsonObject().put("http.port", port)
    );

vertx.deployVerticle(MyFirstVerticle.class.getName(), options, context.asyncAssertSuccess());

这种方式是很简单。打开server socket获取一个随机的端口(这也是为什么将0作为参数)。检索如果端口被占用就关闭socket。需要注意的是,这个方法并不完美,如果端口在socket.close()方法之后和HTTP服务器启动之前被占用的话,会失败。然而,这种情况如果被朋友的话,说明你非常幸运,所以大多数情况下都是没有问题的。

测试一下:

mvn clean test

外部配置-在另一个端口运行

在生产环境中,随机端口并不是我们想要的。所以,在实际执行应用的时候,我们需要将配置写在一个外部的文件里。这个配置的文件使用json格式。

创建src/main/conf/my-application-conf.json,内容如下:

{
  "http.port" : 8082
}

通过执行下面这句命令,在启动应用的时候,加载配置文件:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar -conf src/main/conf/my-application-conf.json

打开浏览器,然后访问 http://localhost:8082

编辑JSON文件,重新打包运行,端口就修改了,不需要修改源码。

这是怎么工作的?fat jar是使用Starter类来加载应用程序。当部署verticle的时候,这个类会读取-conf参数,相应的会创建一个DeploymentOptions对象。

总结

在第一个应用的基础上,只增加了非常简单的代码就完成了Vertx的配置工作。下篇文章我们一起来看看通过vertx-web开发一个提供静态页面和REST API的小应用,这个更加厉害,但是也是非常简单。

Happy coding & Stay tuned !

本人英语比较烂,建议看原文