Vertx worker verticle pool for jdbc

1.9k Views Asked by At

I'm new to Vert.x and I would like to implement a pool of worker verticles to make database queries using BoneCP. However, I'm a little bit confused about how to 'call' them to work and how to share the BoneCP connection pool between them.

I saw in Vertx DeploymentManager source that the start(Future) method is called synchronously and then the verticle is kept in memory until undeployed. After the start method completes, what's the correct way of calling methods on the worker verticle? If I deploy many instances of the verticle (using DeploymentOptions.setInstances()), will Vertx do load balancing between them?

I saw that Vert.x comes with a JDBC client and a worker pool, but it has limited datatypes I can work with because it uses the EventBus and serializes all data returned by the database. I need to work with many different datatypes (including dates, BigDecimals and binary objects) and I would like to avoid serialization as much as possible, but instead make queries in the worker verticle, process the results and return an object via a Future or AsyncResult (I believe this is done on-heap, so no serialization needed; is this correct?).

Please help me to sort out all these questions :) I will appreciate a lot if you give me examples of how can I make this work!

Thanks!

2

There are 2 best solutions below

0
On

I'll try to answer your questions one by one.

how to 'call' them to work

You call your worker verticles using the EventBus. That's the proper way to communicate between them. Please see this example:
https://github.com/vert-x3/vertx-examples/blob/master/core-examples/src/main/java/io/vertx/example/core/verticle/worker/MainVerticle.java#L27

how to share the BoneCP connection pool between them.

Don't. Instead, create a small connection pool for each. Otherwise, it will cause unexpected behavior.

config.setMinConnectionsPerPartition(1);
config.setMaxConnectionsPerPartition(5);
config.setPartitionCount(1);

will Vertx do load balancing between them

No. That's the reason @Jochen Bedersdorfer and I suggest to use EventBus. You can have a reference to your worker verticle, as you suggested, but then you're stuck with 1:1 configuration.

return an object via a Future or AsyncResult (I believe this is done on-heap, so no serialization needed; is this correct?)

This is correct. But again, you're stuck with 1:1 mapping then. Which is a lot worse in terms of performance that serialization (that's using buffers).

If you still do need something like that, maybe you shouldn't use worker verticles at all, but something like .executeBlocking:
https://github.com/vert-x3/vertx-examples/blob/master/core-examples/src/main/java/io/vertx/example/core/execblocking/ExecBlockingExample.java#L25

1
On

In your start(...) method, register event listeners with event bus as this is how you interact with verticles (worker or not). Yes, if you deploy many instances, Vert.x will use round-robin to send messages to those instances.

For what you describe, Vert.x might not be the best fit, since it works best with asynchronous I/O. You might be better off using standard Java concurrency tools to manage the load, i.e. Executor and friends.