But the most common topic that came up seemed to be Quarkus. Quarkus competes with Spring Boot and Micronaut for use in microservice architectures. The framework is designed to be fundamentally reactive, but can still handle imperative code. What has been mentioned again and again in different sessions is the support to build native executables as Quarkus uses Oracles GraalVM. Native images have the advantage that they start the whole application within a few milliseconds and require much less memory than applications running on the Hotspot VM. During the conference, there was a lot of talk about how much faster Quarkus would be with native executables as opposed to Spring Boot. Which made me a little bit suspicious. Which “faster” was constantly being talked about here?
Start time: Yes, much faster
Memory consumption: Yes, considerably lower
But what about Runtime Throughput?Most of my applications should be runtime optimized, whether they need a few milliseconds or a few seconds to start is relatively uninteresting for rolling deployments. If we would run our services as function-as-a-service, it would probably look different.
If you listened carefully, runtime performance was never mentioned. The HotSpot VM optimizes the code more and more during runtime. Statically compiled executables can’t do that. Therefore, all optimizations must be performed at compile time.
Since Quarkus and GraalVM are the hot topics, I wanted to migrate one of my simplest Spring Boot applications to Quarkus. The application reads RSS feeds, extracts links and offers them for download. All this is currently based on Spring Boot with a Thymeleaf UI. The startup time is currently 4s on my Windows laptop and 16 seconds on my RaspberryPI 3b+. On the Raspberry, I would be extremely happy if I could go from 16 seconds to a few milliseconds startup time.
Quarkus uses JEE annotations by default, but has thought about it and offers the extensions “spring-di” and “spring-web”. With the help of these extensions, the applications can be migrated very easily, because all spring annotations simply work. The “spring-data” extension is currently in preview status.
The application.yml or application.properties from Spring must be modified and the dependencies are exchanged in the Maven POM. Quarkus does not know any application class (
@SpringBootApplication), so in my example it could be simply deleted.
Then the problem started that I needed a replacement for thymeleaf, which unfortunately didn’t have a "thymeleaf-starter" as Spring does. A search on the Quarkus site didn’t find it, but Twitter came to the rescue: Quarkus offers a reactive Template Engine named "Qute" in preview status. So I started to change my Thymeleaf template to Qute. Everything went well, then I got to the first loops. If I used a method with a parameter in a loop everything was OK. If the same method had two parameters, the browser would only show an endless loading. There was nothing in the log file, even after I activated the DEBUG level. Soon I reported my first Quarkus bug (https://github.com/quarkusio/quarkus/issues/7144).
After I put together a small example app (https://github.com/mithandir/quarkus-quote-template-bug), the bug was fixed after about 1 week in the “master” branch. Currently, I am waiting for the release of 1.3.0.Alpha3 to finish my migration.
In the meantime, it turned out that GraalVM can build ARM64 native executables, but unfortunately no ARM32 which I need for the Raspberry PI3b+. Only the Raspberry PI4 supports ARM64. It’s about time to order a new Raspberry.
As soon as the small migration is done, I would do some runtime performance tests and then migrate an application that uses Spring Data. Hopefully, the first runtime performance measurements of my applications will follow within the next weeks.
In summary: The Quarkus team has made the migration very easy and the Preview-Extensions are rightly named