So, I happen to find myself with a lot of free time at my disposal. Having spent the last three years head-of-teching in a startup I also have finally the time to think about the technologies we used, the shortcomings, the pitfalls and what I would do different on the next project.
Turns out that I really fell in love with Vert.x as a technology, Java 10 and RxJava2. As you still can see on GitHub we build an awfull lot of components around that. Vert.x is just blazingly fast and easy to understand, RxJava makes for nice reactive streams and modern Java is just fun to work with.
We also had a couple of Spring Boot services, mostly for simplicity and the hype four years ago. In general Spring Boot brings a lot of features, most of them you don’t need or don’t know. It is also quite slow when it comes to startup, in a container, on a VM, in the Cloud.
Now, while I am wondering what to do next and what to do in general I started wondering what I would do knowing what I know now.
We mostly used a stack based on Vert.x, RxJava (sadly 1.x) and Vert.x Jersey. We glued it all together with a couple of abstractions over Verticle deployment and got our own nice stack this way.
Things I would (and have done with newer services) is using RxJava2 as well as replace HK2 with Guice. HK2 is nice but also slightly inferior to Guice in my opinion. For some reason HK2 is not that well maintained, as of last week there was still no support for Java 10 in a released version.
And now I am wondering if I should take this whole stack to a new level and build something like Vert.x Boot, a system that easily lets you bootstrap Vert.x microservices for a variaty of use-cases with the following features:
- Easy to use bootstrapping process like Spring Boot has
- Guice as CI and general application configuration approach (I strongly believe in using code for as many things as possible)
- Vertx-Jersey as a general REST/JAX-RS abstraction
- Metrics and Prometheus integration out of the box using Micrometer
- Defined readiness and liveness probe patterns (health checks)
- Very good RxJava2 integration
- Minimal dependency footprint that is easy to upgrade in order to follow Java’s amazingly fast upgrade cycle
- Some well defined testing and containerization patterns (we all build images now, no?) that make it easy to build “golden” images, maybe using Testcontainers
On top of that there should be some modules to integrate with commonly used data layer services and provide the infrastructure that you usally use around that, like connection pooling and schema migrations:
- SQL, using jOOQ, HikariCP and Flyway for migrations
- Elasticsearch, using vertx-elasticsearch-service and elasticsearch-migration
- Cassandra, using vertx-cassandra and cassandra-migration
- I really like GraphQL, so something that would abstract around GraphQL Java to build easy to use GraphQL endpoints would also be nice
- I’m not so sure about my feelings about Jigsaw and the way the Java eco-system is going, but having a good way to work with modules would also be a bonus.
I used to say that Java is not a great fit for Microservices because of memory usage and startup times, but with this stack it might actually make sense. I haven’t yet figured completely out how low you can go, but with a very low old-gen baseline and requests that always run only in your young-generation you can actually run those things with a very small memory footprint.
Maybe that is something to fill my time with once the summer ends.