This example shows you how to build, package and run a simple Spring Boot microservice as a JAR with GraalVM JDK, and as a native executable with GraalVM Native Image. The benefits of using a native executable are much smaller size, faster start-up times and reduced memory consumption.
We will make use of GraalVM, the Spring Native project and the GraalVM Native Build Tools.
Our microservice generates a random nonsense verse in the style of the poem Jabberwocky (by Lewis Carrol). To achieve this remarkable feat, we use a Markov chain to model the text of the original poem and this model then generates random text that appears like the original.
You will learn how to build, package and run a simple Spring Boot microservice using:
- GraalVM Enterprise in OCI Code Editor
- GraalVM Enterprise in OCI Cloud Shell
- On other machines with Linux or macOS or Windows, follow the instuctions given below.
If you are using macOS or Windows in order to build a Docker image containing your native executable you will need to build the native executable within a Docker container. How to do this is discussed later.
This project is built using Maven. To build the application so that it can be run on-top of a JVM:
mvn clean package
As well as building the application packaged as ajar
, this will also build a Docker image containing the jar
that
uses GraalVM Enterprise Edition as the JVM.
And to run from the command line:
java -jar ./target/benchmark-jibber-0.0.1-SNAPSHOT.jar &
# Add a short sleep to allow the JVM to startup
sleep 4
# Call the endpoint
curl http:https://localhost:8080/jibber
# Bring the app back to the foreground - you can kill it now
fg
To run as a Docker container, the Docker image has been generated by running Maven:
docker run --rm --name graalce -d -p 8080:8080 jibber-benchmark:graalce.0.0.1-SNAPSHOT
You can then test the container suing curl
exactly as you did before - remember to allow a little time for the application to
start up.
We can also build a native executable of our Spring Boot microservice, using GraalVM Native Image. In order to do this the Maven file makes use of plugins from GraalVM Native Build Tools and Spring Native.
When we build it will also generate a Docker image with our native application in it.
To build the native executable version of the application:
# The -Pnative profile is used to turn on building a native executable within the maven file
mvn package native:compile -Pnative
This will create a binary executable target/jibber
. You can run this and test it in the same way as we did the Java
application:
./target/benchmark-jibber &
curl http:https://localhost:8080/jibber
fg
From the log output that the executable outputs, you can see that it starts much faster than the Java version.
If you are linux you can now easily containerise this using the following commands:
docker build -f Dockerfiles/Dockerfile.native --build-arg APP_FILE=benchmark-jibber -t jibber-benchmark:native.0.0.1-SNAPSHOT .
And once that is built, you can test it as follows:
docker run --rm --name native -d -p 8080:8080 jibber-benchmark:native.0.0.1-SNAPSHOT
If you are not using linux as your OS, you will need to do the native image build within a docker container. To do this we have supplied a two-stage Docker build file.
To build:
docker build -f Dockerfiles/Dockerfile -t jibber-benchmark:native.0.0.1-SNAPSHOT .
And once that is built, you can test it as follows:
docker run --rm --name native -d -p 8080:8080 jibber-benchmark:native.0.0.1-SNAPSHOT
The Spring Actuator dependency has been added to the project, along with support for Prometheus. If you want to test the performance of either the JVM version, or the native executable version of the application you can make use of the prometheus support. It will be available on the URL, say if you are hosting it locally on port 8080:
http:https://localhost:8080/actuator/prometheus
And we are done!