Search code examples
javavert.xhttpserver

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


I am staring to learn Vert.x and I just wrote the following 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());
  }

}

I was trying to get the http server creation to fail, so I was expecting an exception saying that port 8080 is already in use when creating server 2. However I get the following logs:

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

I can make sense of the first set where the objects are created, because they might be created before the servers are actually running. I don't understand the one saying Server 2 started successfully

Then when I try to send requests on localhost:8080, I get these logs:

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.

So not only server 2 started, it also eclipsed server 1.

Can someone shed some light on this behaviour so I can understand what happened? And why there were no error or warning?


Solution

  • This is due to Vert.x server sharing feature:

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

    As for why the requests look to be always handled by the second server, can you tell me how you send the requests? From a browser?

    In this case, this behavior is expected. Vert.x uses a round-robin strategy at the connection level. And since browsers keep alive connections, requests sent over a single connection will always be handled by the same server.

    Try with curl or open another browser to see the other server work.