Serverless Architectures - Let's Ditch the Servers?25 Jun 2016
Serverless architecture is a fascinating new(-ish) trend that is quickly gaining momentum. The idea is to be able to run server-side code without worrying about the messy details of provisioning and setting up servers. You write code, upload it and — voilà! — it starts running. All the complications of managing the infrastructure, provisioning servers, auto-scaling, installing languages and frameworks are eliminated and hidden away by the vendor. The vendor takes care of invoking the code in response to a request, providing it the context and input information it needs to do its job and return the result back to the client.
Going serverless requires a slightly different approach to application design. The backend service is broken down into stand-alone functions that perform a single task in response to a user action or event. In serverless architectures, the backend is composed of thin, single-purpose microservices that are event driven and the business logic shifts from the backend to the client. It becomes the main orchestrator, calling various functions to perform some action for the user when needed. For example, running in a serverless architecture, a photo sharing app like Instagram might call one function to upload image to the server followed by another call to a function that reads all the followers’ information from a database and notifies them. Some people have argued that Function as a Service or FaaS would be a better way to describe serverless architectures.
Serverless architectures require very smart clients that know about and talk to a wide range of remote functions. While mobile app developers have had rich frameworks and platforms that allowed them to build complex logic on the client easily, things weren’t so simple for web applications. But thanks to rich client-side application frameworks like AngularJS and a fast HTTP/2 protocol, it is now possible to build complex applications seamlessly into the browser. This will help drive the serverless trend even further.
Amazon Web Services (or the AWS), the undisputed leader of cloud computing, launched a product called Lambda to build and deploy serverless applications.
AWS Lambda lets you run code without provisioning or managing servers. You pay only for the compute time you consume - there is no charge when your code is not running. With Lambda, you can run code for virtually any type of application or backend service - all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app.
Setting up a Lambda function in AWS was straightforward. The only challenge I faced was connecting the function to another AWS product, the API Gateway, to expose it as a REST end-point. Here’s what I learned in the process:
- AWS Lambda currently only supports Java 8, Python and Node.js. You could use a third-party tool to write functions in Go.
- There are many templates to choose from when creating a new Lambda function that could come very handy. They contain examples on how to access various databases and integrate with other AWS products and services.
- Latency is higher after a Lambda function is created, updated, or if it has not been used recently. This can be problematic for certain applications that see intermittent traffic patterns.
- The pricing is based on the number of requests and the duration of script’s execution, billed in 100 millisecond increments. So if a Lambda function runs for 15 milliseconds, it will be billed for 100. This could be an issue for very high-volume applications with lots of short-running functions. A crude hack to get the best bang for the buck would be to combine short-running Lambda operations into a larger one. Also, if you want to expose your Lambda methods as REST end-points using AWS API Gateway, you’d incur extra costs as the API Gateway has separate pricing.
- Lambda functions are stateless and asynchronous which is great, except that it would be wonderful to share a few things like connection pools, that are expensive to setup. Connection pooling isn’t properly supported. Setting up and tearing down database connections for each request increases latency and affect performance.
- Debugging and logging isn’t easy and has a learning curve. When testing my Lambda function, I spent a lot of time scrolling through CloudWatch entries to find issues. Apex boasts to make this easy, but I haven’t tried it myself.
While the AWS Lambda and similar serverless computing platforms are in their infancy, the future looks promising. Not all of us can ditch our servers, at least not yet, but we seem to be moving in the right direction. Infrastructure management is challenging and can be very painful. It shifts the focus away from the real problem to the undifferentiated heavy lifting of managing servers, auto-scaling groups, instance tagging, and even worse, building infrastructure specific logic in applications like the health checks. Development time increases because developers now have the burden of managing their infrastructure. That’s the biggest beef I have with DevOps: it forces skilled developers to spend their time and energy worrying about infrastructure intricacies instead of building useful applications that solve real problems. Serverless architectures take some of these barriers away and reduce the friction that allows developers to get started quickly.