Comparison Camel Quarkus And Camel Spring Boot Graalvm Native
Comparison with Camel Quarkus and Camel Spring Boot GraalVM Native
Today, we show two ways to compile a Camel application to native image and compare their performance: Camel Quarkus and Camel+Spring Boot+Spring Native for GraalVM.
In both cases, the sample application uses the camel-openapi component and Camel REST DSL to illustrate a simple REST services. Here is the source code:
Prerequisites
- Maven 3.6.2+
- JDK 11
- GraalVM 20.3.0
If you have not installed GraalVM 20.3.0, please download from GraalVM Releases at first and get native_image by using
gu install native-image
Also, refer to GraalVM native-image manual if you get problems.
Dependencies
- Quarkus 1.11.0.Final
- Camel 3.7.0
- Spring Boot 2.4.0
- Spring Native 0.8.3
Build the native images
Quarkus
Building a native image on Quarkus is as easy as issuing ./mvnw package -Pnative
:
git clone https://github.com/zhfeng/camel-quarkus-openapi-example
cd camel-quarkus-openapi-example
export GRAALVM_HOME /path/to/graalvm-ce-java11-20.3.0
./mvnw package -Pnative
Note that you do not need to care for configuring GraalVM native-image
tool at all.
Quarkus does it all for you under the hood.
SpringBoot native
To build the Camel SpringBoot application, I had to make some changes to run with spring native library. The steps are as follows:
git clone https://github.com/zhfeng/camel-spring-boot-examples
cd camel-spring-boot-examples
git checkout camel-spring-boot-examples-3.7.0-graalvm
cd camel-example-spring-boot-rest-openapi
export GRAALVM_HOME /path/to/graalvm-ce-java11-20.3.0
./compile.sh
I used the native-image-agent to get the graalvm configuration files. I had to run the application with the agent attached and send some requests so that the agent can record which classes need to get registered for reflection, etc.
Here is what I did:
$GRAALVM_HOME/bin/java -agentlib:native-image-agent=config-out-dir=src/main/resources/META-INF/native-image -jar target/camel-example-spring-boot-rest-openapi-3.7.0.jar
and run curl to send some requests.
curl http://localhost:8080/api/api-docs
curl http://localhost:8080/api/users
native-image-agent
outputs the configuration when the test application terminates.
I have checked in the configuration to git so that you do not need to perform those steps yourselves.
You can also check compile.sh to find the native-image
command to
compile the SpringBoot app.
Performance comparison
As a result of the the previous steps, we got two native executables
(camel-quarkus-openapi-example-1.0.0-SNAPSHOT-runner
and
camel-example-spring-boot-rest-openapi
).
Now we can use the compare.sh script to collect some numbers.
Here are the results on my Lenovo P50 laptop
Runtime | Time to first response | Disk Size | Resident Set Size |
---|---|---|---|
Spring Native | 196ms | 98M | 152204K |
Quarkus Native | 82ms | 97M | 61784K |
We can see that Camel Quarkus native is about 2x faster than SpringBoot native to startup. The Quarkus application also occupies less RSS memory. Camel Quarkus moves more initialization tasks from runtime to the build time. That’s the reason for faster startup time and lower memory footprint.
Acknowledgement
I’d like to thank Peter Palaga for his reviewing and the outstanding suggestions.