Serverless has made building in the cloud easy but we have to be wary of the unique anti-patterns that can creep into our architecture along with the solutions.
Serverless adoption rates have been climbing ever since the technology was brought into the spotlight with the release of AWS Lambda in 2014. That is because serverless makes an offer that cloud developers simply can not resist, providing the following benefits:
These benefits are achieved by the characteristics that define the technology. Serverless applications are stateless distributed systems that scale to the needs of the system, providing event-based and async models of development. This has worked in favor of the technology, resulting in a desirable solution for the cloud.
However, does this offer always live up to what it is perceived as?
With further inspection, there is no doubt that serverless adoption also opens up developers to the possibility of falling into anti-patterns specific to the model. This is especially concerning seeing the high adoption rates of serverless. As more of the industry moves to reap the benefits, we must be wary of what works and what does not work. Serverless is definitely beneficial, however, the wrong use of it could leave a sour taste, pushing the industry away from the technology.
Therefore the purpose of this piece is to highlight the anti-patterns that plague serverless architectures and how they may be avoided. Hence enabling the success of serverless applications and also promoting its adoption.
Serverless applications tend to work best when asynchronous. A concept that was preached by Eric Johnson in his talk at ServerlessDays Istanbul titled “Thinking Async with Serverless”. He, later on, went to present a longer version of the talk at ServerlessDays Nashville.
Nevertheless, the same asynchronous characteristic that is revered is also the source of one of the greatest anti-patterns. In understanding why this is the case, it first needs to be remembered that one of the benefits of Serverless is the pay-as-you-go model. Therefore, when a function or a service is waiting for a response from another function or service that has been called upon asynchronously, the first function is in an idle state. Simply waiting for the second function’s response.
This is the result of converting from monolith to serverless architectures without paying attention to detail. For example, in a monolith system, a method may want to perform a read/write operation to DynamoDB. However, to avoid waiting for the operation, and blocking the control flow, the call may be made asynchronously, allowing the method to call upon another method to perform some other task, but still waiting for a response from DynamoDB at the end of the method. The second method may in its own way begin S3 operations.
This logic when being moved to serverless, can not be done in the same manner. This is because intuitively each method can be mapped to its separate serverless function, but it must be remembered that these functions can timeout or simply finish their remaining tasks and become idle waiting for callbacks.
As a result, the function that is in the idle state will also be charged since it is still technically active. There is still a worker node servicing the function with all the needed underlying architecture as the function simply waits.
This problem is further exasperated when chaining functions together. This is the process whereby one function makes an async call to another function, waiting for a response, while the second function is called upon another function or makes a read/write operation to a storage service.
This increases the possibility of unreliability as the first function might time out. This is even worse when functions make calls to storage devices outside the vendor’s ecosystem, or on-prem storage services.
The solution is not to abandon asynchronous patterns, because the issue does not lie in async calls but the way such calls are incorporated. For example, it is often the case when decomposing the monolith, that there are controller functions, managing the transfer of data. This leads to unnecessary costs and also increases the unreliability of functions in terms of possible timeouts.
The solution, in this case, is simple and involves rethinking the control flow. Therefore the function structure above could be transformed into the structure of a function as seen below:
Coding Best Practices. Serverless Architecture Best Practices With AWS Lambda. The serverless architecture best practices with AWS Lambda. Serverless applications that are well designed are separated, stateless, and utilize minimal code.
Micronaut is creating a buzz around cloud-native application development due to its enriched features and optimizations based out of modern Polyglot JVM.
Companies need to be thinking long-term before even starting a software development project. These needs are solved at the level of architecture: business owners want to assure agility, scalability, and performance.
In the world of cloud technology, there are three vendors that reign supreme, and this article briefly outlines some of the merits and use cases for each. AWS vs. Azure vs. Google: Which Is the Best for Cloud Computing?
Learn AWS cloud concepts, AWS services, security, architecture under AWS cloud practitioner course from AWS certified instructors. Authorized AWS Training