BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Presentations Serverless Java

Serverless Java

Bookmarks
36:12

Summary

Ivar Grimstad presents a gentle introduction to serverless and FaaS, what it means for developers, and why it is important to understand this paradigm. He then turns to solutions available for developing serverless applications, or functions, with Java.

Bio

Ivar Grimstad is a Java Champion, Oracle Groundbreaker Ambassador and JUG Leader working as Principal Consultant for Cybercom Group in Sweden. He is the PMC Lead for Eclipse Enterprise for Java (EE4J) and involved in the forming of Jakarta EE.

About the conference

Software is changing the world. QCon empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.

Transcript

Grimstad: I'm a member of the Java community, processing and the executive committee. I'm also a member of the Jakarta EE Working Group where I'm the PMC for the EE for J projects and this is all within the Eclipse Foundation. I'm also a NetBeans committer at the Apache Foundation and I run a local Java user group in Malmo. I'm a Java champion and I'm an Oracle groundbreaker ambassador.

Usually, my talks are on the topics of Jakarta EE or micro profile. I do have some Jakarta EE stickers here, so if you want to stick around afterwards for questions or something, so please come up and get them. I don't want to fly them back home to Europe. Today I'll talk about serverless, I'll introduce a little bit too serverless and some of the concepts then I'll go through some of the offerings out there and do some demos using Java then and just sum up a little bit at the end.

What Is Serverless

What is serverless, then? First of all, it's a very bad name, and why is it a bad name? There are still servers, it's just that these servers are somebody else's server. Somebody else is taking care of everything - the setup, the infrastructure, the scaling, everything considering the servers. What it really is, it's no server management, it's serverless abstracts away all of the underlying infrastructure so you can focus on the code and the code only. You can develop your application faster and better and iterate faster than ever before.

Serverless is also automatic scaling. You can serve your users of your applications or functions from zero to planet scale, without even thinking about the infrastructure underneath because you don't manage your servers yourself. You just write your functions and you let somebody else take care of it.

It's also a payment model. With serverless or cloud functions, you only pay for the time your function is actually running or being executed. If you compare to a traditional server where you have some applications running in a web server, for example, you pay for all the time when the web server is just lying around there waiting for requests but with serverless, you only pay when the code actually runs.

It's event-driven. Serverless allows you to trigger your code from any type of event you can imagine. It could be something happening on an event queue or it can be an HTTP request, or it could be a timer request. We are actually running some batch jobs with a function, so we just have a timer that gets these jobs going.

It's very open and familiar in the means that there are no new languages created for serverless, there are no serverless programming languages. You use the familiar tools and the languages that you're used to use, and most providers let you pick and choose whichever language you want to use.

Serverless is also known as, functions as a service or FaaS or even cloud functions. If you look at this typical kind of majority stack or layers of the cloud infrastructure or as a service services, you usually start at the bottom with the infrastructure as a service which is typically like EC2 in Amazon. If you add some kind of platform services on top of this, you get platform as a service and this is typically like Google App Engine. Then a layer over that is some container management or containers you can run your applications in. For these days, for example, Azure container service by Microsoft or Oracle App Container Service.

Based on stuff in these layers, you can build your applications on top of this with functions coming between the containers as a service and the application layer in this pyramid. We only care about the stuff on top here because everything else underneath whatever it's the container as its platform, its infrastructure, whatever is going on down there, that is somebody else's job. We just want to write our functions and our applications that use our functions.

What about architecture then? What are the implications for application architecture when you introduce functions? In serverless, there is a preference for choreography over orchestration and that means that every component is more aware of its role in the architecture. In choreography, it's more like in the microservices world where you decentralized that every service knows its place in the architecture whereas when you think about orchestration is more as a central component that manages things.

What's in it for developers for serverless then? First of all, there are no servers, so we don't have to manage these. Also, it's easier because, as a developer, you can now focus only on the functionality, only about the code that actually drives your business, you don't have to think so much about the infrastructure and the scaling and everything underneath, you just write your function and deploy it somewhere.

It's faster. You can deploy it faster because everything is already up there so you just have to write your stuff, you can then deploy faster, iterate faster, innovate faster. It's cheaper, if you want to test out something and just write a function and see what you can use with it, you will only pay for the milliseconds that you were actually executing your function and not for an entire infrastructure set up to test this stuff. It'll also super powerful, if you write a function and you suddenly have a lot of traffic on it, it scales automatically, it manages automatically, you don't have to think about, "I have to buy some new hardware or something to have my application run on it."

What's in it for business then? It's kind of the same things that applies for developers. The agility lies in the fact that since developers move faster with less dependencies and innovate faster, you can move your application and iterate faster over it. You can innovate faster because since developers can just throw a function up in some cloud environment, you can just test out new ideas very quickly without having to set up an entire server product to do it.

It's also cost reduction, you only pay for the execution of your functions and not for the idle time. It also means that you can reduce your operation costs because when you don't have people managing your servers you can just have people managing your cloud environment which is much easier.

What about Java Functions then? We all know that Java kind of starts slow. It has a big memory footprint, it's not very well suited for functions. That is the old thinking because it's getting better and it's getting faster and it's getting smaller all the time. Still, if you're running plain Java on a JVM, you probably want to avoid Java Functions for the most extreme scalability needs.

That is also changing because we have this technology called GraalVM that solves a lot of their stuff. GraalVM compiles Java byte code to native images and it uses ahead of time compilation, so we build the dependency graph before you started so the JVM can start up much faster. Since you also can compile it to native, you get the size of it down, so it's smaller and it's faster.

I put up an example here from Red Hat and Quarkus. You can see the Quarkus REST application starts in a couple of milliseconds while a regular Java-based similar app would start in 4 seconds or something. If you want to learn more about Quarkus you should go to the session that is after this one where Quarkus will be demoed.

How about Frameworks? Can I use Spring in my functions for example? Yes, you can. You can pull in any framework you want to do but what you need to be aware of is, the more dependency you drag into your function, the slower it will start, so think about this and the use case you're using function for. If you're running a function for a batch job that is going to run by timer trigger during night, it doesn't matter if it takes a couple of seconds to start-up because it will run for a couple of minutes anyway. If you want something to scale like a voting app, you probably don't want to be pulling too much into a function.

FaaS Implementations

That was what I thought to talk about when it comes to serverless and the small limitations with Java. Now I'll change and go into talking about the different FaaS implementations out there and I'll demo a couple of them.

First of all, we have OpenFaaS. OpenFaaS is serverless functions made simple for Docker and Kubernetes. It's an independent project and it is a growing community being built around it. The website and blog and everything are on openfaas.com. When I checked it didn't support Java, that can change [editor's update 23rd August: thanks to a comment from Alex Ellis, creator of OpenFaaS, we were keen to mention that the framwork has supported Java since July 2018] . That's why I put three dots there because every time you write these slides, they update to something and you have to add stuff, so they might well as well support Java now, I'm not sure.

Then you have Apache OpenWhisk which supports Java and a lot of other languages. I'll demo Apache OpenWhisk in the context of IBM Cloud afterwards. Then, of course, you have Google Cloud Functions, they support Node.js and Python. I don't think they support Java, I'm not sure if they actually have any plans of supporting Java either. Google also is behind the initiative called Knative. Knative is a set of components so we can build and run serverless applications on Kubernetes It's Docker and Kubernetes underneath and it offers features for scaling, for clusters and an event frameworks and everything. It's kind of cloud-native applications on Kubernetes for functions. Since it's in Docker containers, you can write it in whatever language you want.

Then, of course, we have AWS Lambda which is the first one out there and they support Java and a bunch of other languages as well. I was thinking I should demo AWS Lambda. I am using sort of the same application for all the demos and it's super simple. It is just saying hello to some name or hello world if nothing is said. In AWS, you have dependencies for the Lambda core, the Java APIs there. Simply just write a class that implements the request handler and has the input and output. The request handler has a method called handle request and here I can have the person which is the input to the function. I can do, for example, user context to get the login and unlock things directly into the AWS runtime. I can return the string which is in this case is hello and whoever comes in there.

This is built using the Maven Shade Plugin, so it a super simple configuration. This is my entire palm file and just build a jar and then you can upload it to AWS. You can do that using Amazon Command Line tool, I'll just do it in the web console. It creates a jar here, it's about 10K, so it's not that big. We have this Lambda core and, of course, if I dragged in here a dependency for some framework with a couple of megabytes on it, the file will be a couple of megabytes.

In Lambda, you search up your AWS Lambda console and you can go click function, I'll take the simple one, myDuke. You can see all the runtimes that it supports, probably Java 11 is coming around the corner. I'll click “Create function”, and you can, of course, do this with a template or the client tooling. It should be up and running pretty fast. My function is created, so now I have to upload my code, so I choose the jar I created. I also have to give it the method signature of the function I've written. This is the package, this is the class, and this is the method. That's all I need to do to create it, it's up there.

If I want to test this function, I'll create a test event, I'll call it myDukeEvent. If I remember, it was a person with a name and that was the only attributes that'll send in to it. It's a JSON string here and look at the person it has as a name attribute. This is how it maps, let's put it there and then I'll create my test event. Now, I should be able to test my function using the myDuke test event. It executes my function and I can see here it says, "Hello Duke." That's how easy it is to create this practically one line of code and package it in a jar and upload it and you're good to go.

The next one I'm going to demo is IBM Cloud Function. As I said, it builds on Apache OpenWhisk, they built some client tooling on top of OpenWhisk. You can do it natively in OpenWhisk or you can use the IBM tooling and it supports Java, as you see. Let's go in and look at this. The IBM Duke is very similar to the Lambda Duke but here, I don't even have to implement an interface. I'm using JSON as a dependency here, so that's my only dependency. Here I also use the Maven Shade Plugin to create my artifacts. It's super simple configuration.

What I do here, I take in a JSON object and I return JSON objects. Just grabbed the name from JSON object and return JSON saying that contains this greeting. Since my IBM account doesn't support functions because you have to pay for it, I'll do it locally. They have this IBM cloud scripting or client tooling. If I do IBM Cloud FN action lists, it will list all the functions I have locally, and I have a demo Duke and a Duke Java. These are just somewhere I've created before, so I'll have something if it fails.

If I wanted to create a new one, I say action create, I can call it Hello Java. I point to the shaded jar which has been produced by the Maven and then I point to the main method which is your agile Java hello or the main class. The configuration is very similar to the AWS one. I just don't have to give it the method name because here the method name is a static method called name.

I create it and when it's created, I can see that it's here and I can also execute it. I say invoke and I say I want the result printed here. I am working the hello Java function and I am sending in Duke as a parameter. It returns greeting Hello Duke which is what you expected. It's pretty fast, it's pretty ok, unfortunately, you do have to put your credit card up there to be able run it in IBM cloud.

The next one I'm going to demo is Azure Functions by Microsoft. They support a variety of languages, also Java of course. Since February the Azure functions is not GA for Java. Previously its been early access or beta release but now they actually support it. They have chosen a little different path, the code is very much similar. I have a simple class which I have method in but here I annotate it with some functional stuff.

I'm using the Azure Functions libraries to annotate this one, this is my function. Here I can also tell which trigger I want to use. It could be a timer trigger or HTTP trigger or trigger by something else or I can write my own trigger, probably. I can do whatever I want. In this case, I would say it should be HTTP trigger and that trigger is on get and post. Here, also, I can use the context to reamplicate the logger and interact with the cloud platform. I'm getting a query string out of the request and returning "Please pass a query string" if there are no string there and not saying hello to the string that I've passed in. Microsoft has provided some tooling for us. You can add some functions here about your cloud accounts and subscriptions.

They have this Java library that you can use to interact with the platform and have this Maven Plugin, so you can use to build your function. For Azure, you write maven clean package reasonable and Azure functions run, if you want to run it locally. You can log in using the Azure client tooling and say Azure functions deploy and it will deploy to a client account.

Here I'm running it on local host. If I go in here and say name is Duke, it says "Hello, Duke." In Azure, it looks like you have a function app and if deployed you'll see it here and you can actually test it using the URL directly. Here I can define the function in the JSON description and I can get the URL for the testing it. This is a function I've uploaded earlier for the same function. It's pretty fast and pretty easy to integrate with if you have some Maven tooling with Microsoft.

The last one I'm going to demo is Fn Project. Fn supports Node, Java, Go, Ruby and Python. Fn is supported by Oracle, so I'll demo Fn locally and on Oracle cloud. With Fn, the function is super clean and easy as there are no libraries you have to import. Just write your code, it's a classical hello function, it's called handler request, you can call it whatever you want. This one uses a configuration called assistant environment variable to name if it has anything in input and it writes hello to that name.

What Fn also has is a descriptive file, you give it the Java version you want run and the method signature and some triggers. In this case, I chose an HTTP trigger. Here's the paradox with serverless because the first thing I have to do is, you can guess, start my server. It starts pretty quick. I have my server up and running, I can have a different context in Fn.

Here I have one pointing into Oracle Cloud Infrastructure, so I just have to point it to my local one to run the local. Then I can say Fn build, to build my function. I'm just feeling it won't work locally because I'm using the registry from this one but let's try it anyway. Let me check my readme file there - yes, I have to say that there's a local one.

I'm uploading this to the cloud so let's go to the cloud demo rather than the local one. What I have in the Oracle cloud console here is still an early access, so you have to request it to get access but when you do, it's pretty straight forward, you get a lot of instructions of how to do it. I'll just log into the functions console. Also, here they've chosen to have this kind of app concept, a function app which has a couple of functions. Here I have this Fn-duke which you can see as the parameter world configured.

If I want to invoke the function, I can use the Fn tooling to do that. Here it starts up the function in the cloud environment and executes it. The first time you do it, it has to do spin up stuff. This is where the Quarkas compiled or GraalVM combined native image would be much faster. While this one goes, we can look at other ways of invoking functions.

Oracle has provided a Java API, so you can write your own function, a color. You have to set some variables because of the security in Oracle cloud, so you have to have a signed requests, so you cannot just do HTTP request, at least I haven't figured out how to do it without or disabling the security. You have to have a certificate that you sign your request with. You have to set up some environment to do that.

Apart from that, it's more or less just to build a function request and send it over. It's pretty straight forward when you start looking at the code. I'll do it in the command line. You see here it says, "Hello world." If I go into the UI here and delete the configuration and I call the function again, it should now say "Hello to Null" because I don't have any parameters send to it. It also allows me to configure my functions using the Fn tooling.

I can say fn.config function, give it the FunctionDuke and say name Duke. If I call it again, it will say "Hello Duke." It's a pretty nice tooling, Fn it's nice and smooth to do. Your code looks probably the simplest of the four I've called because we don't have any dependencies in there, and you don't need any plugins. Today it's supports at least Java 9, I think they support Java 11 as well. You have this fn tooling outside of it, so your Java code looks really clean and nice and it's pretty decent to use.

Summary

To sum up, the functions on Java are coming, all the vendors support it. They have different approaches to it and you may feel that we're moving away from this. I write my function somewhere and I can run it everywhere because you get in a situation where we have to tie into the cloud vendor. With Fn, you're separated the most from it, so all the configuration is outside of your code and maybe some kind of standard way of defining it would have been nice. You can always get around it by writing your function in the library and have your actual invocation of the function just where you communicate with the infrastructure and just call to that library. You can always get around it if you want to port your functions to from different vendors.

With native compilation supported by Graal, all the memory issues and the store pages are gone, so it starts up in milliseconds, it's fast enough. The samples from this talk are on my Github and here I've listed all the different interpretations I've have been showing today.

Questions and Answers

Participant 1: The cold start [inaudible 00:35:07]

Grimstad: Graal is one answer to that question. If you can compile your code to native code, it starts in literally milliseconds, so it's just as fast as Go or Javascript or any other runtime. If you have to load a lot of things, Java as it is today is doing a lot of things dynamically so that would be slow if you start everything from beginning. I think the different cloud vendors are also looking at how to keep things warm without you paying for it. That will also solve it but that is a cost and issue. I think the native compilation and ahead of time compilation is probably the way to go.

 

See more presentations with transcripts

Recorded at:

Aug 14, 2019

BT