0
votes

It seems that a verticle is only ever executed by a single thread and always by the same thread. But Vert.x is capable of using all the CPUs in the machine by creating one thread per CPU. Each thread can send messages to multiple verticles.

But when profiling a vertx http server on a standard verticle during a performance test, I can only ever see 1 thread handling all the processing (vert.x-eventloop-thread-0).

What can I do to have all 8 of my event loop threads processing messages to the verticle?

CountDownLatch latch = new CountDownLatch(1);
final List<Throwable> errors = new ArrayList<>();

local = new Local(getVertx(), settings, options, connectionHandler, exceptionHandler);

LocalVerticle.vertxDeployMap.put(local.hashCode(), local);

DeploymentOptions dop = new DeploymentOptions()
        .setInstances(new VertxOptions()
        .getEventLoopPoolSize())
        .setConfig(new JsonObject().put("local", local.hashCode()));

Network.getVertx().deployVerticle(LocalVerticle.class.getName(), dop, (event) -> {
    if (!event.failed()) {
        latch.countDown();
    } else {
        errors.add(event.cause());
    }
});

boolean await = latch.await(10, TimeUnit.SECONDS);
if (!await) {
    if (errors.isEmpty()) {
        throw new Exception("Failed to initialize Local Verticle");
    } else {
        throw new Exception("Failed to initialize Local Verticle", errors.get(0));
    }
}

LocalVerticle.vertxDeployMap.remove(local.hashCode());


public class LocalVerticle extends AbstractVerticle {

    static final Map<Integer, Local> vertxDeployMap = new HashMap<>();
    
    private HttpServer httpServer;

    @Override
    public void start() throws Exception {
        
        Local local = vertxDeployMap.get(this.config().getInteger("local"));

        HttpServerOptions options = local.getOptions();
        Handler<HttpConnection> connectionHandler = local.getConnectionHandler();
        Handler<Throwable> exceptionHandler = local.getExceptionHandler();
        Router router = local.getRouter();

        this.httpServer = this.vertx
                .createHttpServer(options)
                .exceptionHandler(exceptionHandler)
                .connectionHandler(connectionHandler)
                .requestHandler(router)
                .listen();

    }

    @Override
    public void stop() throws Exception {
        if (this.httpServer != null) {
            this.httpServer.close();
            this.httpServer = null;
        }
    }
}
1

1 Answers

1
votes

The Vert.x threading model is designed so that a particular instance of a deployed Verticle is always locked to a single thread. In order to scale your application across cores, you need to deploy multiple instances of your Verticle.

When deploying a verticle using a verticle name, you can specify the number of verticle instances that you want to deploy:

DeploymentOptions options = new DeploymentOptions().setInstances(16);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

This is useful for scaling easily across multiple cores. For example you might have a web-server verticle to deploy and multiple cores on your machine, so you want to deploy multiple instances to utilise all the cores.