Hello! I'm really new to Vertx and have some questions regarding proper use of worker threads from the worker pool versus worker verticle for my Java app.
Basically, I've been testing out deploying worker verticles and I'm confused on their differences and why they impact my app so vastly differently
Currently my app is setup to execute roughly like this:
- App starts up and creates vertx with its options, the only non-time related one is worker pool being set to 20
- From here we deploy a new verticle that runs createHttpServer with separate routes
- When we get a client request, it goes to our routes and their handler functions, which then run the requests through our entire code logic. I believe this is simply using one (or some, not sure) of the worker threads from the vertx worker pool.
- After the first big synchronous block of code runs, we enter the point where we're waiting on DB queries and futures to complete. Our DB clients are created with JDBCClient.createNonShared(vertx, JsonObjectOfConfigurations)
- Once we receive them all, we finish our code and respond to the user
Things to note:
- We only deploy a single verticle throughout the whole app's lifetime, the one that creates the server
- All logs show [vert.x-eventloop-thread-0] despite it still running requests concurrently
- If I setup event handlers, such as routingContext.request().connection.().closeHandler(..), they won't execute until step 3 moves onto step 4. (Note: I create this handler during the execution of each route's logic from within that request's routingContext.) Presumably this is because the eventloop has to finish its queue before reporting events under this implementation. This is actually what led me to try the second approach
- If a request comes in during a huge blocking operation, it isn't started until said operation has finished
Under the new proposed approach, it executes roughly like this:
- App starts up and creates vertx with its options, the only non-time related one is worker pool being set to 20
- From here we deploy a new verticle that runs createHttpServer with separate routes
- Same logic, but instead of letting vertx use a worker thread, I'm specifically deploying a worker verticle to run the entire logic instead. The only deployment option I explicitly set here is setWorker(true)
- After the first big synchronous block of code runs, we enter the point where we're waiting on DB queries and futures to complete. Our DB clients are created with JDBCClient.createNonShared(vertx, JsonObjectOfConfigurations)
- Once we receive them all, we finish our code and respond to the user
Things to note about this implementation:
- That connection().closeHandler(...) mentioned above actually executes in real time now
- Now only the first few app logs mention [vert.x-eventloop-thread-0], while most others mention [vert.x-worker-thread-X]
- Now if a request comes in during a huge blocking operation, a different worker simply takes it up and begins its processing in parallel
- It increased our app's performance under concurrent load by about 500% somehow, it's actually kind of crazy so it made me skeptical, but our data quality and validation tests seem to be checking out too
I believe the source of the initial implementation's issues stem from putting huge blocking processes on the eventloop. I'm not sure why the other 7 eventloop threads aren't being used so that may be another solution to this issue, but I don't know how to utilize them.
Is this new implementation ok? I've read that worker threads are ideal for blocking processes, but I've had answers on stackoverflow tell me that this is incorrect because we shouldn't deploy verticles per request. I believe this is a sort of niche case where we have huge blocking processes per request.
Also I noticed that after some time I'll see a lot of single ERROR lines in the logs, and I'm assuming these are the old verticles decaying out of memory. So I'm guessing I need to undeploy each one at the end of the request life to avoid undefined behavior/errors, right?
Thanks for any help or clarifications!