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?
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.