vert.xvertxoptions

Vertx http server instance number does not improve throughput


I am using Vertx 3.8.0 to build a http server. The CPU can not be utilized (Only about 25% of CPU can be used) even when I set the instance of the verticle to number larger than 1. The instresting thing is the best performance I can get is when I set the instance number to 1.

public class Runner {
    public static void main(String[] args) {

        VertxOptions vertxOptions = new VertxOptions().setPreferNativeTransport(true);
        vertxOptions.setEventLoopPoolSize(6);
        final HttpServerOptions options = new HttpServerOptions()
                .setTcpFastOpen(true)
                .setTcpNoDelay(true)
                .setTcpQuickAck(true);

        final Vertx vertx = Vertx.vertx(vertxOptions);

        DeploymentOptions deploymentOptions;
        deploymentOptions = new DeploymentOptions().setInstances(3);
        vertx.deployVerticle(() -> new AbstractVerticle() {
                    @Override
                    public void start(Future<Void> startFuture) {


                        vertx.createHttpServer(options)
                                .requestHandler(req -> {
                                    req.response().end("1");
                                })
                                .listen(8080, "0.0.0.0");
                    }
                }, deploymentOptions
        );
        System.out.println("Deployment done with pooling");
    }

}

I used apache benchmark to test throughput of the server.

 ab -c 150 -n 100000 http://10.32.31.35:8080/api/values/

The throughput result in about 8k per second. The server only utilize about 25% of the CPU. If I use keepalive of http, the throughput is about 48k with about 50% CPU.

I used JMX to monitor the server program. It seems like that the instances number setting actually worked. There are more than 1 eventloops processing the requests, but it's likely the acceptor event loop is the bottleneck.

Is there anyway to improve this? I think multiple instance of vertx would help(Like docker) but isn't there any more elegant way to utilize the computing resource?


Solution

  • There are some invalid assumptions with this test:

    1. You think you are deploying 3 servers, but they're deployed on the same port, so only one actually listens. And deploying more servers doesn't increase you concurrency anyway
    2. Your test doesn't utilize event loop that much. Most of your time is wasted on establishing new connections. That's why you see "improvement" while using keepalive. It's pure networking, not Vert.x
    3. Make sure you run ab on a separate machine, or you're competing on the same resources
    4. Don't expect to see some kind of 100% CPU utilization anyway, as you're not doing anything CPU intensive, actually