Hi Dominic,
TLDR: endpoint = handler, verticle = deployment unit, not a tool to define modules, never share something across verticles directly ( the instance of an router) unless you really know why you are doing that (i.e. db client might be a good to share if it is thread safe).
I am not sure if I understand your problem, but I see a familiar pattern here. So I will assume that your problem is a form of "too many verticles" design flaw. Don't worry it seems that most new apps in vert.x starts there (at least mine did).
My assumptions:
- you have one machine or all machines run the same verticles
- you have about 30 verticles running in single JVM
- your services are more endpoints than services or "nano" services - conceptually they are not separate paths
I might be wrong and my answer might be irrelevant.
So to start, do you have a machine with over 30 CPUs? I guess not. So why would you create 30 verticles?
Every single verticle has its own thread with event loop. If you have many verticles, you have more threads than CPU can handle without switching back and forth between threads. If we can stop switching context == keep a number of threads low - we have a significant gain in performance. If we can't we just waste a lot of time on
https://en.wikipedia.org/wiki/Context_switch . To be able to process many requests we need some blocking threads for IO but actual processing should be async and run on event loops. Such architecture allows having much higher throughput than classic servlet == thread.
So we want to keep a number of threads low and be able to scale at the same time.
How? It is actually pretty simple. I would say that what you need by default is One Verticle. Unless there is a Very Good Reason not to have more than one. Most of the time the reason is not very good. Good is not enough, it must be very good IMHO. You might want to use separate verticles to deploy completely separate services, that don't share ports nor code, to deploy different services in single JVM. But this is rather for a near service - an app deployed on someone's PC, phone, raspberry pi at home, not a service which runs on a server and is exposed to internet scale traffic, as this would be slow (where slow is something that can't respond in < 10ms, it still will hit Doherty threshold).
If you have one verticle you can easily scale it up just by increasing number of its instances. Because the system is homogenous it is trivial. There is no problem with ports or shared router. The router is not shared, but the HTTP server you create can use the same port. In normal cases, it would also be faster as you will have a lower number of threads and no context switching.
Threat Verticle like a war - it is your deployment unit, not a way to modularize your app. You modularize your app with handlers, classic OOP, Guice, OSGi...
Depending on how you develop the services/endpoints (one team, many teams), how big they are etc. you might want to do different things.
To show to different options one would be simple handlers another would be kind of di.
Handler based:
- all routeing is being set in one main verticle and for every route, a handler is provided
- handler does not know it's path, the verticle does
- one can use sub routes to better manage complexity
- this way is simple and can be taken quite far, with good oop skills it would also be really easy to read, but you need to now all services up front
And on another side of the spectrum
DI based:
- you have a generic verticle that deploys a server and run trough a list of route configurations in order
- a configuration takes a router and registers all needed handlers (it knows it's path)
- the route is injected to verticle trough Guice, CDI, spring or custom mechanism
- the DI tool finds all possible services that you want to run and injects it to the verticle
- this way you can develop every single service as a separate project put it in jar and deploy in one verticle
Be aware of threads you have, not only verticles create threads, some db clients will create their own thread pools, you don't want to have too many threads.
Hope that helps,
Krzysztof