Part 1 - Comparison of Spring Boot versus Quarkus in memory consumption and startup times. We also show Quarkus' live code updating.
Part 2 - Implements a popular use case for Quarkus in Native mode - as a serverless workload on Kubernetes, in our case the industry leading Kubernetes distribution, Red Hat OpenShift.
Available on You Tube at https://youtu.be/bMkcVYTW8Z8
We take two very simple and pretty identical RESTful applications, one Spring Boot, the other Quarkus. We compare memory consumption and startup times in
- Spring Boot
- Quarkus in JVM mode
- Quarkus in Native mode We also briefly demonstrate Quarkus' live code updating capabilities.
We then push our native application as container to the popular Quay container registry and from there we pull it into a KNative Serverless application running on OpenShift.
To run the first part of this demo, you'll need Java (I use version 8), Maven and GraalVM installed. To run the second part, you'll need an OpenShift 4.4 cluster. I recommend Codeready Containers for a local cluster or try.openshift.com for a full production ready cluster. You'll also need access to a public container registry. I use the excellent free one from http://quay.io.
Clone this repo and change to its directory. Then:
export REPO_HOME=`pwd`
cd $REPO_HOME/springboot-hello-world
mvn package
java -jar target/springboot-hello-world-1.0.0.jar
Take note of the startup time - you can see mine took 2.258 seconds
Also take note of the memory consumption - under rss (Resident Set Size) in the following command
ps -o pid,rss,command -p $(pgrep -f springboot)
And of course - test your application
curl http://localhost:8080/greeting
Stop Spring Boot by clicking CTRL + c
cd $REPO_HOME/quarkus-hello-world
mvn package
Now run it
java -jar target/quarkus-hello-world-1.0-SNAPSHOT-runner.jar
Take note of the startup time - you can see mine took 0.667 seconds
I created a sheet that shows
- how many times faster Quarkus is to start up than Spring Boot (in both JVM and Native mode).
- what percentage of Spring Boot's memory requirement Quarkus has.
Quarkus' 0.667 seconds startup time is more than 3 times faster than Spring Boot's 2.258 seconds - for an identical application:
Now take note of the memory consumption, rss:
ps -o pid,rss,command -p $(pgrep -f runner)
You can see mine consumed 158,696k of memory
Quarkus used about a quarter of Spring Boot's memory for effectively the same application:
And again - verify your application
curl http://localhost:8080/greeting
Stop Quarkus by clicking CTRL + c
Stay in directory $REPO_HOME/quarkus-hello-world Now compile the application down to a native image using GraalVM (for instructions on how to set this up - go to https://quarkus.io/guides/building-native-image)
mvn package -Pnative -Dquarkus.native.container-build=true
Now after mvn package run it:
./target/quarkus-hello-world-1.0-SNAPSHOT-runner
Again take note of the startup time - you can see mine took 0.012 seconds
That's nearly 200 times faster than Spring Boot - for an identical application:
Now take note of the memory consumption, rss:
ps -o pid,rss,command -p $(pgrep -f runner)
You can see mine consumed 18,258k of memory
Quarkus in Native mode uses about 3% of Spring Boot's memory for this hello world application:
And again - test your application
curl http://localhost:8080/greeting
Stop Quarkus by clicking CTRL + c
ps -o pid,rss,command -p $(pgrep -f runner)
This demo focuses on the startup-time and memory advantages of Quarkus over a traditional cloud native stack like Spring Boot. Quarkus has several another benefits - like the ability to combine imperative and reactive programming in the same application, user friendly error reporting, and a superb extension network. But a massive benefit of Quarkus is live code updates. When running in dev mode, to see code, package, maven dependency changes, all you need to do is save the file - no need to rebuild.
Let's test this out. Execute the following to startup in dev mode
cd $REPO_HOME/quarkus-hello-world
./mvnw compile quarkus:dev
Test out the app:
curl http://localhost:8080/greeting
Now, keep the app running but make a change to a source file - say this file's default message:
Save the file. Test it again:
curl http://localhost:8080/greeting
Your application now reflects the change you did without a rebuild!
cd $REPO_HOME/quarkus-hello-world
First we need to package our native application into a container image using the provided Dockerfile (/quarkus-hello-world/Dockerfile.native) and push it to our remote container registry. First login to your remote container registry, using podman login or docker login then execute the following or your equivalent according how you want to tag and name your repo:
docker build -f ./Dockerfile.native -t <registry-username>/<repo-name>:latest .
docker tag <registry-username>/<repo-name>:latest <registry>/<registry-username>/<repo-name>:latest
docker push <registry>/<registry-username>/<repo-name>:latest
or in my case:
docker build -f ./Dockerfile.native -t tnscorcoran/quarkus-serverless:latest .
docker tag tnscorcoran/quarkus-serverless:latest quay.io/tnscorcoran/quarkus-serverless:latest
docker push quay.io/tnscorcoran/quarkus-serverless:latest
On http://quay.io, I label my new repo quarkus-serverless with latest
When I then make this new repo public, as shown, it will be available to pull into my cluster.
Next login to your OpenShift cluster as an adminstrator.
Now we're going to provision our Serverless Operator, which will allow us to create a new KNative serverless runtime for our application.
Go to Operators -> Operator Hub -> search for serverless and choose the OpenShift Serverless Operator:
Click Install
Click Update Channel 4.4 and Subscribe.
We need a project / namespace called knative-serving (it needs that name). Create as follows
With your new project knative-serving selected, we will deploy the knative serving API. As follows
Move to Workloads -> Pods and wait until all are ready and running:
Next we're going to pull in our Quarkus container image and run it in Serverlesss mode. To house our new Quarkus Serverless application, create a new namespace/project, in my case I call it quarkus-serverless:
Now it's time to pull in our Quarkus image in Serverless mode. Change to the Developer perpective, choose Topology and create an application from a container image as shown:
Choose the registry/repository you created earlier, in my case quay.io/tnscorcoran/quarkus-serverless. Choose KNative Service and accept the other defaults:
Note if you want you can modify the scaling defaults using the Scaling link at the bottom of the screen. By default it scales to zero after some seconds, which is great for saving cloud costs and we'll experience below.
After a few seconds the application is available - as indicated by the sold blue circle. Click on the URL link
Then append /greeting and you can see the JSON payload returned from this simple API endpoint:
Finally after about 30 seconds, the application scales to zero as shown. Any request will waken it very quickly thanks to Quarkus Native's rapid startup times you saw earlier.
Quarkus is a new Open Source Red Hat sponsored Java framework. It's designed with cloud native development and Kubernetes in mind.
It's got radically lower memory and faster startup than traditional cloud native Java (we used Spring Boot to represent that). The advantages are most pronounced in Native mode - making it an ideal candidate for Serverless workloads. Serverless and scale to zero can dramatically reduce your cloud infrastructre costs as machines can be powered down to zero in quiet periods.
Quarkus in JVM mode, also advantages are still significant - making it the best choice for longer lived applications where JVM capabilities, in particular Garbage Collection, are needed.
We demonstrated the following
- 2 applications, both identical in functionality; one Quarkus and one Spring Boot
- the compartive startup times and memory consumption in a) Spring Boot, b) Quarkus in JVM mode and c) Quarkus in Native mode
- a really cool feature of Quarkus - live code update.
- an outstanding use case of Quarkus Native mode - serverless on Kubernetes. We used the industry leading Kubernetes distribution Red Hat OpenShift.
To learn more about Quarkus visit Red Hat build of Quarkus and https://quarkus.io
This demo can be viewed on You Tube at https://youtu.be/bMkcVYTW8Z8.