Don’t replace Spring Boot with Quarkus, replace it with Wildfly
The title of this article could also be: The only reason to use microservices or Stop using microservices.
This is the view of a developer that thinks software should be easily maintainable and durable. Built to last a decade, at least, like anything else that is valuable.
The software industry is, for some time now, being led by trends, hypes and seasonal technologies/frameworks. It’s good in one point of view. Many new technologies and concepts arise from that. But, in consequence, that is leading to low quality, low durability and expensive software. Developers are willing to use new shining things and forget to ask one important question: what problem can this new thing solve that my old thing can’t?
Low quality software appears because developers are, more often than ever, fighting with new versions of their frameworks. By wasting time fixing framework breaking changes, by being unable to update their software to a new version or by rewriting their software, this behavior is bringing their already solved bugs back again.
Hypes and cargo cults are also leading to expensive software, with the wrong and unnecessary adoption of microservices and containerization technologies, which adds costs and complexity with no gain at all.
The false promises of microservices
Developers around the world are on a move to break down their monoliths into microservices. And they base this move on false assumptions. We already have many companies moving out of microservices back to monoliths. Microservices are now at the “Trough of Disillusionment”, in the Gartner Hype cycle. These false assumptions are:
- Only microservices are scalable: FALSE. There are no metrics or methods that can be used to classify a code base as microservice or monolith. Even a 2 pizza team can be responsible by a monolith or by a microservice. It’s possible to scale both of them.
- Only microservices code are easy to maintain: FALSE. If you have 5 developers responsible for a microservice, it’s already hard to reason about. It’s large, huge. If you call it a microservice or a monolith, it doesn’t matter. The number of lines of code are the same. You can organize your monolith into small modules so they can be easy to understand.
- Microservices are small: FALSE. The word “micro” is misleading. Of course you can have a small microservice, but the recommendation is that microservices should not be so small that one developer can handle it alone. You’re only adding complexity and cost doing that. And again, you can have small and independent modules in your monolith.
- Microservices are resilient: FALSE. Resilience is a matter of how you organize your modules or microservices and how they can still work on the presence of errors. You can have truly independent modules in a monolith that will work flawless or have 2 microservice bound by an HTTP call where it will only work when both are online only. Microservices are a distributed system, with a lot of moving parts. It’s much harder for it to be resilient than of a monolith.
Microservices hype and cargo cult
So, why people are using microservices? Why everybody is talking about it? Cargo cult and hype.
Microservices are the way big companies found to allow a huge amount of developers to work on a single product.
Take for example the company that started all that: Netflix. They have one big product. One. How could be possible for 100 developers to work on the same git repository or code base? It’s physically impossible. That’s why they did it. And that is the only reason to use microservices.
Microservices architecture is a way to allow a huge amount of developers to work on the same product. Nothing more than that.
That’s why it won’t make sense within enterprise software. Enterprise developers are normally responsible for many applications. It’s rare to have 15 developers working exclusively on one application. If you have this situation, so yes, microservices will work for you. If your application have 15 exclusive developers, you can break your application into 3 or 4 microservices for example and divide your team to work exclusively on them.
For all the rest of us, enterprise software developers, we should be writing monoliths. But, not any monolith, a modular monolith. We want all the benefits microservices claims to provide within our monoliths. How can we do that? How can we build software that last, scalable, easy and cheap to maintain? Application servers, backward compatibility and upfront design.
It turns out that our industry stop considering backward compatibility and upfront design to be valuable things and that an application server can’t have the same role of a docker container.
This issues were solved in the past, so we must bring it back: Jakarta EE. Adam Bien made this enlightening presentation entitled “Build to last” that shows the path we should take. We can also add to this, a presentation from Axel Fontaine “Majestic Modular Monoliths" that completes the reasoning I will show you.
The “cloud ready Java” hype
Spring Boot, Quarkus, Micronaut, etc. are frameworks to build microservices in Java. Sure you can write a monolith on top of them. But, while they are important to test and create new technologies that seeds Jakarta EE and vice-versa, they’re not a good fit for enterprise software. Sorry.
The initial cost is high, because you will need to setup a secure container cluster, load balancers, message queues and other stuff. And pay for support, of course. You also spend more RAM using them. If you deploy an application made by 4 microservices, or modules, this is the amount of RAM used (OpenJ9):
- Quarkus (1.12.1) + ActiveMQ (2.17.0): 4x 67MB +193MB = 461MB (JAR size: 34MB)
- Spring Boot (2.4.3) + ActiveMQ (2.17.0): 4x 126MB + 193MB = 697MB (JAR size: 48MB)
- Wildfly Full (embedded ActiveMQ) (22.0.1) = 284MB (EAR size: 21KB), yes KB!
They are far from being memory and disk efficient. Another issue is, although these Java frameworks tries to be backward compatible, from one version to another, we can get some breaking changes. Enterprise software should last. So, within a decade, your code will break if you choose them. You should choose Jakarta EE if you want a really solid, stable and up to date foundation to your application. Upfront design, remember?
Wildfly as Jakarta EE implementation, message queue and container platform
Do these stacks looks similar?
Yes, they are. They fulfil the same roles. Now that you know you should choose Jakarta EE as framework for enterprise software, why don’t you choose an implementation that provides not only Jakarta EE, but the whole microservice infrastructure? Wildfly is a complete implementation of Jakarta EE backed by Red Hat, that provides much more functionality than the specification. It has, for example, an embedded ActiveMQ message queue, that can be used by your modules for asynchronous communication. It also provides a security vault, that can be used to store passwords and sensitive strings. It can be run in domain mode, to load balance and replicate data throughout the cluster. Jakarta EE is already a container platform, so your modules or applications can run in isolation and be deployed independently of each other. It also provides you with a web console to administer and monitor your application server. And I just scratched the surface. So, can Wildfly replace a cloud platform for enterprise software? Yes.
- Kubernetes: Container image | Wildfly: WAR package
- Kubernetes: Deployment descriptors | Wildfly: EAR package
- Kubernetes: Standalone ActiveMQ | Wildfly: Embedded ActiveMQ
- Kubernetes: Config Secrets | Wildfly: Security Vault
- Kubernetes: Complex operation | Wildfly: Simple operation
- Kubernetes: High cost | Wildfly: Low cost
- Kubernetes: Horizontal scalability | Wildfly: Vertical scalability
- Kubernetes: Isolated and independent deployments | Wildfly: Isolated and independent deployments
- Kubernetes: Third parties monitoring tools | Wildfly: Embedded monitoring tools
- Kubernetes: High RAM usage | Wildfly: Low RAM usage
What about scalability? Again, ask yourself: do you need scalability? How much? Upfront design, remember? Enterprise software doesn’t require huge amounts of hardware. If your application will have 10000 concurrent users, one server is enough. Actually, it’s very affordable (in enterprise standards) at Amazon an EC2 machine with 40 cores and 128GB of RAM. So, you can vertically scale your applications a lot. That’s probably the total hardware of a complete kubernetes cluster that you would use to scale your application horizontally, but wasting memory on each server runtime replica. Which makes no sense, since application servers runs on top of the JVM. People forget about the “V” in JVM. It’s already a virtualized environment. A kubernetes cluster is a waste of hardware. Just allow your JVM to use all available cores and memory, and let the JVM and Wildfly do the rest.
These Java cloud technologies make you think they’re memory efficient, but they show only one running service. If your application have more than 4 microservices, you’re wasting RAM.
It’s important to test and know what’s is new in the software development industry, so you can see it’s benefits and drawbacks of each one. But, you must be diligent and cautious. Don’t be led by hypes and trends. It’s part of your job to say no to things you don’t need. It’s hard, I know. You must design your architecture upfront, asking how much time does this software should exist. And choosing a platform that allows the healthy existence of the software during it’s lifespan.
It’s fun to test new things and you should do it. But, only that. Tests and proof of concepts to see if you’re not solving a problem your platform already solves. For real big projects, choose stability and future proof technologies, that will allow you to spend your weekends not writing software. Software that is built to last.