Getting to know Fn (part II): Generating an Fn function with Java and GraalVM

We continue today with our series of introductory posts about Fn Project. If last week we talked about what Fn Project and the concept of serverless are, today we want to go a bit further and show you how to generate an Fn function using Java and GraalVM, a virtual machine that can execute code from different programming languages.

What we are going to do today is to recreate the function we prepared last week, the «HelloFunction» one, but in its GraalVM equivalent; and then we will measure image sizes, boot times, memory consumption, etc., to compare them.

As you will see, it’s not complicated at all, so let’s get on with it.

Creating the function

Let’s start by creating the function, for which we’ll use the «fn-java-native-init» image, invoking it with the following code:

fn init –init-image fnproject/fn-java-native-init java_fn_graalvm

cd java_fn_graalvm

Once these lines are executed, we will be able to see that the GraalVM function also generates the Dockerfile to generate the native «GraalVM multi-stage» image:

Creating the application and measuring its weight

Next, we are going to generate an app by launching the following code:

fn create app java_fn_graalvm-app

Next, we are going to modify the example to make it the same as the Java application we created in the previous entry. Finally, we will deploy the application (we will see that the first generation of the image takes a long time). To do this, we will execute the following command:

fn deploy –verbose –local –app java_fn_graalvm-app

Once the deployment is done, we can check the image size of both versions. The original Java version has a weight of 238 MB:

On the other hand, the GraalVM image is only 40 MB – six times less than the Java version:

Checking runtimes

Now that we have seen the big difference in weight between the two versions, let’s see if the execution times differ much.

We’ll start by checking the original Java version, using the following command:

time curl -X “POST” -H “Content-Type: application/json” -d ‘{“name”:”Luismi”}’ http://localhost:8080/invoke/01F00Z4AHENG8G00GZJ0000007

Next, we will do the same but with the GraalVM image:

time curl -X “POST” -H “Content-Type: application/json” -d ‘{“name”:”Luismi”}’ http://localhost:8080/invoke/01F03G9FPANG8G00GZJ000001N

In our case, the differences are only noticeable in the first execution of each function, since at that moment Fn has to instantiate the function image, where the time is reduced by 30%. Once instantiated with the image in memory, the times are very similar between both versions.

In a real example, such as an Fn function built on top of Spring Cloud Function, the differences would be more significant as the startup of a Spring Boot application with GraalVM is much faster.

We would also like to point out that the time difference depends on whether or not Fn has to instantiate the image for execution, something which can be configured with the Fn Runtime options:

Having said that, this second entry about Fn can be over.

We hope you found it interesting and that you can get value from it. As always, if you have any questions, please leave us a comment.

✍🏻 Author(s)

One thought on “Getting to know Fn (part II): Generating an Fn function with Java and GraalVM

Leave a Reply

Your email address will not be published. Required fields are marked *