Serverless with Java – advantages, limitations and use cases
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 the 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 nano service).
- 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 the serverless approach, your development team is able to focus on code that fulfills your business requirements.
- Easier maintenance
Not only could the setup of the serverless solution be easier than in the traditional approach, but also its maintenance requires less effort. You do not manage infrastructure manually. You can rely on services with built-in scalability and monitoring.
- Lower costs
Faster development and easier maintenance mean that the overall costs of the system are lower. Additionally, the 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 a high, stable workload, a serverless solution could be more expensive.
- Easier prototyping
With a 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 the existing market space and when creating one before your competitors. Time is money and serverless could be very time effective.
- Constant improvements
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.
The developers are shaping modern technological world
What are the most promising technologies for software development?
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 a serverless approach to our partner we always do a calculation based on the 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 the Infrastructure as a Code (IaaS) approach, proper versioning and testing strategy with an experienced team, big systems are deliverable.
- Limited time
In some clouds, the 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. The traditional containerised application should be faster and cheaper.
- Vendor locked-in
Even in an example of the 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 a serverless framework that allow you to deploy your serverless solution to different clouds.
- Cold start
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 the 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 the big workload or because the first instance becomes 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 the user interface, using dedicated instances (MS Azure). Additionally, cloud providers are still improving their services to minimise the 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 a 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 start
Cold starts of Java functions take longer than cold starts of functions written in interpreted languages. Java packages are usually bigger. The runtime environment is heavier. In the case of backend application half of a second or even a second of latency is not a problem. In the case of an interaction with a user, it could be an issue.
- Overall performance
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 their 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.
FinTech application development using Java
Having been around for over two decades, is Java the most reliable technology?
When should we consider serverless with Java?
Java is a widely used software language. In some areas, like in the 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 solutions. 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 the 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.
- Partial solutions
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 handling 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 a 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 a 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.