Serverless Native Java Functions using GraalVM and Fn Project

TL;DR;
Java Functions compiled into a native executable using GraalVM reduces cold start times and memory footprint by order of magnitude compared to running on JVM.
Native Java Functions performs equal to or better than Go functions in terms of execution time and memory used.
Native Java Functions executable runs from scratch base image, thus have a similar size compared to Go executable images.
Source code is available at https://github.com/panga/fn-native-java

panga/fn-native-java

fn-native-java - Fn Project Native Java Function using GraalVM
github.com
What’s GraalVM?
GraalVM is a High-performance polyglot VM open sourced by Oracle and currently in active development.

It also has the ability to compile JVM languages and a few other languages like JS, Python, Ruby and R into native executable. Some examples are demonstrated in @graalvm blog.

The executable actually runs in a optimized native VM called “SubstrateVM”. Although is quite stable nowadays, it still contains some limitations that are currently being worked on and can be released in near future.

What’s Fn Project?
The Fn Project is an open-source container-native serverless platform that you can run anywhere — any cloud or on-premise. It’s easy to use, supports every programming language, and is extensible and performant.

It is an evolution of the IronFunctions project from iron.io and is mainly maintained by Oracle. So you can expect enterprise grade solution, like first class support for building and testing.

It basically leverages of the container technology to run and you can get started very quickly, the only prerequisite is Docker installed.

First, you need to install and start Fn Server using the following commands:

curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
fn start
The Fn introduction tutorial explains how to run your first function, while the Java introduction tutorial shows the Java function example.

Creating a Native Java Function using GraalVM
What’s a Native Java Function?
I will call any Java code that is compiled Ahead-of-Time (AOT) into a native executable that does not require a JVM to run as Native Java Function.

What problem does it solve?
Java is often blamed as being heavy and not suitable for running as serverless function.

That fame does not come from nothing, it sometimes needs a full JRE to run with slow startup time and high memory consumption compared to other native executables like Go.

Fortunately this isn’t true anymore, with new versions of Java you can create modular applications, compile Ahead-of-Time and have new and improved garbage collectors using both OpenJDK and OpenJ9 implementations.

GraalVM is new flavor that delivers a JVM that supports multiple languages and compilation into native executable or shared library.

Steps to create your first Native Java Function using GraalVM
Create a new Java function with fn init --runtime java8 myfunction
Create reflection.json for enabling reflection in the function entrypoint

  1. Create Dockerfile using GraalVM CE base image provided my me

  2. Change func.yaml to use docker runtime and add build commands:

  3. Build and deploy the function

fn deploy --app myapp --local
6. Call the function

curl -d ‘Leonardo’ http://localhost:8080/r/myapp/myfunction
Note: More advanced use cases using fnproject/fdk-java are also working.

Benchmarking
All the benchmarks are done using my local machine (MBP 2015) with default function templates created using Fn Cli.

The executions were done using the following command:

curl -d ‘Leonardo’ http://localhost:8080/r/myapp/myfunction
Cold Execution Times
Java Function -> 660 ms
Native Java Function -> 460 ms
Go Function -> 470 ms
Note: Most of the time consumed in cold execution of Native Java Function and Go Function was the container startup, the real execution time is near 0 ms.

Hot Execution Times
Java Function -> 30 ms
Native Java Function -> 30 ms
Go Function -> 30 ms
Container Memory usage of Hot Function
Java Function -> 17.8 MiB
Native Java Function -> 0.9 MiB
Go Function -> 1.2 MiB
Container Image Size
Java Function -> 266 MB
Native Java Function -> 13.6 MB
Go Function -> 15.1 MB
Conclusion
It is a good time to start trying Java Functions on Serverless solutions!

Update on 2018–06–24
Changed Dockerfile from alpine base image to scratch in order to demonstrate the independence of generated native executable.

Thanks Codrut Stancu!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值