DEV Community

Niklas Heidloff
Niklas Heidloff

Posted on

Lightweight serverless Java functions with Quarkus

Quarkus is a “next-generation Kubernetes native Java framework” which is available as open source. Quarkus promises fast boot times and low memory usages. This makes Quarkus a perfect fit for Java workloads running as microservices on Kubernetes as well as Java workloads running as serverless functions.

Read the article Why Quarkus to learn how Quarkus works. In a nutshell Quarkus compiles Java source code in native binaries via GraalVM. The Quarkus framework helps developers to easily build applications that can leverage the GraalVM benefits.

Most developers use JavaScript/Node.js to build serverless functions nowadays. One reason is that Node.js applications usually (used to?) start faster and consume less memory. Since you typically pay for memory and time in the cloud, Node.js often saves you money and provides better experiences.

Today I looked briefly into how to use Quarkus to build lightweight and fast Docker images which can be run as serverless functions on Apache OpenWhisk based platforms like IBM Cloud Functions. One of the great features of OpenWhisk is that you can use Docker to develop functions.

I’ve put together a little sample on GitHub.

Here is how you can try Quarkus on IBM Cloud Functions. All you need is a free IBM Cloud lite account and the ibmcloud CLI.

First download the code:

$ git clone https://github.com/nheidloff/openwhisk-quarkus-starter.git
$ cd openwhisk-quarkus-starter

Before the actual Docker image is built, the native binary is created. Follow the instructions on the Quarkus web site how to set up GraalVM, a Java JDK and Maven.

Then build the image (replace ‘nheidloff’ with your Docker name).

$ mvn package -Pnative -Dnative-image.docker-build=true
$ docker build -t nheidloff/quarkus-serverless:1 .
$ docker push nheidloff/quarkus-serverless:1

In order to invoke the function locally, run these commands:

$ docker run -i --rm -p 8080:8080 nheidloff/quarkus-serverless
$ curl --request POST \
  --url [http://localhost:8080/run](http://localhost:8080/run) \
  --header 'Content-Type: application/json' \
  --data '{"value":{"name":"Niklas"}}'

In order to change the implementation of the sample function, use your favorite Java IDE or text editor. When you run the following command, the application will be updated automatically every time you save a file:

$ mvn compile quarkus:dev

The OpenWhisk function can be created on the IBM Cloud with these commands:

$ ibmcloud login
$ ibmcloud fn action create echo-quarkus --docker nheidloff/quarkus-serverless:1 -m 128

Note: The deployed Quarkus function only consumes 128 MB memory. I think this is pretty amazing.

The easiest way to invoke the command is via the ibmcloud CLI:

$ ibmcloud fn action invoke --blocking echo-quarkus --param name Niklas

Next I want to look more at the speed of the Quarkus functions.

Top comments (3)

Collapse
 
dwamara profile image
Daniel Wamara

How long did "mvn package -Pnative -Dnative-image.docker-build=true" took time to complete? On my machine it takes nearly 28 to 30 minutes which I find non-productive.

Collapse
 
steinwachs profile image
andreas • Edited

Mine took about 9 minutes on the first run. This, of course, includes download times for the dependencies. Total time: 09:09 min.

The second run, which did not need any further downloads, took significantly less time: 03:03 min

[openwhisk-quarkus-starter-runner:10]    classlist:  12,930.98 ms
[openwhisk-quarkus-starter-runner:10]        (cap):   3,529.01 ms
[openwhisk-quarkus-starter-runner:10]        setup:   8,478.68 ms
03:16:03,992 INFO  [org.xnio] XNIO version 3.6.5.Final

03:16:04,992 INFO  [org.xni.nio] XNIO NIO Implementation Version 3.6.5.Final
03:16:12,417 INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Alpha4
[openwhisk-quarkus-starter-runner:10]   (typeflow):  42,474.59 ms
[openwhisk-quarkus-starter-runner:10]    (objects):  42,903.53 ms
[openwhisk-quarkus-starter-runner:10]   (features):   2,534.91 ms
[openwhisk-quarkus-starter-runner:10]     analysis:  89,625.62 ms
Printing call tree to /project/reports/call_tree_openwhisk-quarkus-starter-runner_20190904_031729.txt
Printing list of used classes to /project/reports/used_classes_openwhisk-quarkus-starter-runner_20190904_031732.txt
Printing list of used packages to /project/reports/used_packages_openwhisk-quarkus-starter-runner_20190904_031732.txt
[openwhisk-quarkus-starter-runner:10]     universe:   1,283.34 ms
[openwhisk-quarkus-starter-runner:10]      (parse):   5,196.04 ms
[openwhisk-quarkus-starter-runner:10]     (inline):   6,101.22 ms
[openwhisk-quarkus-starter-runner:10]    (compile):  29,021.28 ms
[openwhisk-quarkus-starter-runner:10]      compile:  42,617.14 ms
[openwhisk-quarkus-starter-runner:10]        image:   4,603.47 ms
[openwhisk-quarkus-starter-runner:10]        write:     746.02 ms
[openwhisk-quarkus-starter-runner:10]      [total]: 169,176.46 ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:03 min
[INFO] Finished at: 2019-09-04T13:18:23+10:00
[INFO] ------------------------------------------------------------------------
Collapse
 
codingsaint profile image
Coding Saint

What is your system configuration , on latest systems I have seen it taking less than 5 minutes. I. Software everything is tradeoff while it is helpful to build fast , we surely don't do prod builds every time while coding, having said that GraalVM should improve on build timing.