Serverless is not a new idea but it is becoming more and more popular. The possibility to delegate infrastructure setup and maintenance to a cloud provider and focus only on code that handles business logic seems very appealing.
But what if you want to go serverless but your current systems are written in Java and you do not want to introduce other languages like Node.JS or Python? The good news is that you can build serverless solutions with Java language that is fully supported by most important cloud providers like Azure or AWS. Please note, however, that it is not always the best idea to use Java or even to build a serverless solution at all. As experienced developers and software architects at Future Processing we are always concentrated on our customers’ needs. It is crucial to build optimal solutions, rather than those that include as many buzzwords as possible (although many of these buzzwords, like serverless, are connected with great benefits that could be gained in some cases).
Why does it make sense to go serverless?
A serverless model is very simple: you upload code that does something and trigger its execution in response to a chosen event – generated by the system or by the end user (for example via http request). In other words: there is one or more function(s) as a service (FaaS) integrated with other cloud services using events. For example, in AWS we can use API Gateway (that serves http request), Lambda (FaaS that handles business logic) and DynamoDB (that stores our data) to create rest endpoint (we can consider this solution to be a simple micro- or nanoservice).
Simplification of software delivery
Building a system using cloud services and writing as small an amount of code as possible is very effective. You do not want your developers to “reinvent the wheel” while creating boilerplate, administration, security, monitoring (…) code. Solutions in these areas available in the cloud are both reliable and cost effective. With serverless approach your development team is able to focus on code that fulfils your business requirements.
Not only could the setup of serverless solution be easier than in traditional approach, but also its maintenance requires less effort. You do not manage infrastructure manually. You can rely on services with build-in scalability and monitoring.
Faster development and easier maintenance mean that overall costs of the system are lower. Additionally, pricing model of services like Azure Function or AWS Lambda seems to be very attractive: you are charged only when your code is running (price depends on execution time and resources usage). It is perfect when your system or its parts are used irregularly. On the other hand, for a system with high, stable workload, a serverless solution could be more expensive. Serverless is not always a perfect solution.
With serverless approach, developers can prepare prototypes smoothly and verify which solution is optimal.
Time to market
Finally, with this lightweight approach, your solution could be ready for production quickly. In many cases it makes a big difference both when trying to beat the competition in existing market space and when creating a before your competitors. Time is money and serverless could be very time effective.
Cloud solutions are being improved by their providers all the time. Using managed cloud services, you receive all these improvements without a need to invest your time and money.
Serverless is not always a perfect choice
At this moment you may ask: ’If serverless is so perfect then why isn’t everything serverless?’ Well, serverless is not perfect. It is an excellent tool but it should be used in proper cases by experienced professionals.
Not cost effective
I’ve already mentioned that serverless solutions could be not cost effective. Before proposing serverless approach to our partner we always do a calculation based on customer’s statistics or predictions. Cost differences between a traditional and serverless solution could be large.
Big systems as a challenge
It is easy to configure and develop small serverless applications. It is much harder to provide a big system using this approach. You’ve probably heard about dependency or event hell. In a serverless approach you can have another one: functions hell. But with Infrastructure as a Code (IaaS) approach, proper versioning and testing strategy in experienced team big systems are deliverable.
In some clouds, time of function execution is limited (for example to 15 minutes), while in others there are no limits. But generally, functions should be executed quickly without much I/O. If you have long-running computations in your system or a lot of heavy I/O operations, then probably serverless is not for you. Traditional containerised application should be faster and cheaper.
Even in an example of simplest serverless solution we’ve used 3 AWS specific services: API Gateway, Lambda, DynamoDB. Of course, in other clouds we’ll find similar ones (in Azure: API Management, Functions, CosmosDB). Similar, but not the same. Potential migration won’t be for free. Fortunately, there are tools like serverless framework that allow you to deploy your serverless solution to different clouds.
Serverless does not mean that servers are gone. Virtual machines and containers are still there, but carefully hidden and managed by cloud providers. Before executing your code for the first time, a lot of operations must be performed, including:
- Allocation to server with free resources
- Downloading of your function
- Starting container
- Starting runtime environment (for example JVM)
Just after performing these heavy operations your code is executed. That’s a cold start. Next calls could reuse this already warmed up instance (code is executed at once) until there is a need to prepare another one (because of big workload or because the first instance became inactive after being idle for a long time).
There are many ways to handle this problem: hiding it by proper design of an application, pre-warming function instances, not exposing functions to user interface, using dedicated instances (MS Azure). Additionally, cloud providers are still improving their services to minimise impact of cold starts.
Why is Java not a perfect language for serverless?
Although Java is supported by cloud providers, it is not the first-choice solution when thinking about serverless system. Nevertheless, it is unlikely that Java will ever be as performant as interpreted languages like JS (Node.JS) or Python in serverless solutions.
Cold starts of Java functions take longer than cold starts of functions written in interpreted languages. Java packages are usually bigger. Runtime environment is heavier. In case of backend application half of a second or even a second of latency is not a problem. In case of an interaction with a user, it could be an issue.
After a cold start, a difference in performance between compiled and interpreted languages is usually not so much visible, but, still, Java is for sure not the leader. So, if you want to create your system from scratch, then you should consider more performant languages.
Java applications usually use at least a bit more memory than its competitors. As a result, you could be forced to allocate more memory to your function. If you are billed for both time and memory consumption, then your bills could be higher.
When should we consider serverless with Java?
Java is a widely used software language. In some areas, like in financial sector, most of the applications are created in Java. It is possible that your software uses libraries that are available only in Java. In this case, it is probably the best solution to stay with Java while going serverless.
Existing code (team)
If you have software written in Java and a team that develops and supports it, then introducing another language could not be optimal. It’s easier to have everything in Java. You can reuse existing code. Same developers could work easily with both existing and new serverless solution. Switching to serverless is usually not easy for the team. Its members need to learn new approaches and tools. It is not a problem in a big company like Future Processing, where each team or team member could rely on support of experienced technical advisors. But, still, it is a challenge and there is no need to make it even harder by introducing a new programming language.
Migrations to the serverless approach could be done in small steps. It is not an ‘all or nothing’ decision. Containerised applications could work well along with a function dedicated to handle certain events (sending emails, auditing changes, purging data, doing some background tasks etc.).
GraalVM and the future
Today, it is possible to use GraalVM to transform Java bytecode into native executable that could then be executed as a function in the cloud. The main benefit of this approach is a noticeable reduction of cold start time and memory footprint. Although this concept seems to be simple in theory, it’s quite cumbersome in practice. Nevertheless, GraalVM is a tool that could make Java serverless solutions much more performant in the future.
Good decisions and good software
When you are considering serverless solution, you need a partner that has enough experience to advise you whether or not to go serverless, which language and tools to use. And then, you need developers with proper skills to implement it well. If you’d like to learn more about serverless or Java solutions, please contact us. We can help.