Vert.x 在同一个 Verticle 中创建 2 个具有相同端口的服务器

Vert.x create 2 servers with same port in same Verticle

我开始学习了Vert.x我刚写了下面的Verticle

public class HelloVerticle extends AbstractVerticle {

  private static final Logger LOGGER = LoggerFactory.getLogger(HelloVerticle.class);
  private int counter = 0;

  @Override
  public void start() {
    HttpServer server1 = vertx.createHttpServer()
      .requestHandler(r -> handleRequest(r, 1))
      .listen(8080, httpServerAsyncResult -> {
        if(httpServerAsyncResult.succeeded()) {
          LOGGER.info("Server 1 started successfully on port {}", httpServerAsyncResult.result().actualPort());
        }
      });

    HttpServer server2 = vertx.createHttpServer()
      .requestHandler(r -> handleRequest(r, 2))
      .listen(8080, httpServerAsyncResult -> {
        if(httpServerAsyncResult.succeeded()) {
          LOGGER.info("Server 2 started successfully on port {}", httpServerAsyncResult.result().actualPort());
        }
      });

    LOGGER.info("server 1:{} | port:{}", server1, server1.actualPort());
    LOGGER.info("server 2:{} | port:{}", server2, server2.actualPort());
  }

  private void handleRequest(HttpServerRequest request, int serverId) {
    String remoteAddress = request.remoteAddress().host();
    LOGGER.info("Request {} served by server {}.", counter++, serverId);
    request.response().end("Hello " + remoteAddress);
  }

  public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    vertx.deployVerticle(new HelloVerticle());
  }

}

我试图让 http 服务器创建失败,所以我期待一个异常,说明在创建服务器 2 时端口 8080 已被使用。 但是我得到以下日志:

20:47:00.281 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - server 1:io.vertx.core.http.impl.HttpServerImpl@92f7c0 | port:8080
20:47:00.281 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - server 2:io.vertx.core.http.impl.HttpServerImpl@3a4b9d63 | port:8080
20:47:00.283 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Server 1 started successfully on port 8080
20:47:00.283 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Server 2 started successfully on port 8080

我能理解创建对象的第一组,因为它们可能在服务器实际 运行 之前创建。 我不明白Server 2 started successfully

然后当我尝试在 localhost:8080 上发送请求时,我得到这些日志:

20:47:20.952 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 0 served by server 2.
20:47:21.531 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 1 served by server 2.
20:47:22.204 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 2 served by server 2.
20:47:22.848 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 3 served by server 2.
20:47:23.517 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 4 served by server 2.
20:47:27.928 [vert.x-eventloop-thread-0] INFO chapter2.hello.HelloVerticle - Request 5 served by server 2.

所以不仅服务器2启动了,它还使服务器1黯然失色

有人可以阐明这种行为,以便我了解发生了什么吗?为什么没有错误或警告?

不禁止多个套接字监听同一端口如果端点是用"reuse address"选项打开的。

这通常是不可取的,因为传递在某种程度上是任意的。尽管该选项对于避免 TCP 定时等待状态的问题很有用。

推测您正在使用的框架应用了“重用地址”选项。

这是由于 Vert.x server sharing 特征:

When several HTTP servers listen on the same port, vert.x orchestrates the request handling using a round-robin strategy.

至于为什么请求看起来总是由第二个服务器处理,你能告诉我你是如何发送请求的吗?从浏览器?

在这种情况下,这种行为是预期的。 Vert.x 在连接级别使用循环策略。由于浏览器保持活动连接,通过单个连接发送的请求将始终由同一服务器处理。

尝试 curl 或打开另一个浏览器以查看其他服务器是否正常工作。