AWS Serverless and Microservices — Part 2
Continuing with our Design Journey of YAFDP Application using AWS Serverless Stack from earlier parts —
Part 1 — How to structure Microservices using AWS Serverless stack and using Synchronous Request-Response pattern with API Gateway and Lambda
Part 2 (This blog) — Covers Designing of Asynchronous event submission using API Gateway, SQS and Lambda. And how to implement Saga Orchestration Pattern with Serverless Step Function service.
Part 3 — Covers approach of sending the status of asynchronous task submission, in our case New Food Order Placement, to the client.
Part 4 — Covers Placing New Food Delivery Order using Choreograph Saga Event Driven Pattern.
Part 5 — Using Serverless stack for designing Notification Service.
Team O, the owner of Order service, started with the implementation of the end point for placing the Food Delivery order. And here is what they come up with—
For simplicity, I have assumed that all the services provide Synchronous request/response Rest APIs for processing the requests (I know reality is far more complicated than this, but for now let’s assume it 😏)
Back to flow now, placing a new order triggers a business work flow which involves communication with multiple micro services —
On receiving request for new Food Delivery Order, following actions are performed on server side —
- Save order in the Database with status as Pending.
- Initiate Payment using Payment Service
- On confirmation of Payment, confirm/place order with Restaurant.
- On confirmation of order from Restaurant, initiate scheduling of Food Delivery.
- Notify the end user with success message and the time of delivery (this is important, don’t forget this 😃)
- And finally, update the status of the Order as Confirmed in the Database.
At high level, this looks OK. But it has got some flaws —
- It is assumed that the complete order flow — either success or failure will complete in less than 30 seconds, which is the hard limit timeout for an AWS API Gateway endpoint. This is a big risk, and we will have to handle the request in asynchronous way.
- If one of the downstream service invocations fails because of some temporary network glitch or because of throttling issue, the retry logic has to be configured in the New Order endpoint. Adds complexity to the business logic.
- If any of the step execution in the business flow fails, then all the steps for rollback needs to be handled, making the New Order endpoint more complex to deal with.
- If YAFDP system becomes a great success, and the inflow request for placing orders is way higher than what could be handled by downstream systems. For example — If Payment service integrates with 3rd Party Application which is not as scalable as the YAFDP platform is then the overall volume handling capacity of the system is dependent on the Payment Service volume handling capacity.
Let’s try to handle the above issues in Approach 2, where Team O discussed with one of the other teams who had done some analysis of Serverless stack in AWS.
In the above approach, Team O has made following changes:
- Added SQS in the system which is integrated with API Gateway New Order endpoint. When Gateway receives new order request, it adds the request to the SQS and immediately returns unique SQS ID back to the caller for tracking purpose. SQS is highly scalable, hence system is much more scalable now in terms of accepting the orders. Rate of processing of the orders will still be dependent on the least performing service.
- Added AWS Serverless service Step Functions as an Orchestrator for New Order Business flow. Error handling and retries logic is managed by Step Functions. So, the Lambda functions (Microservices) becomes light on code and just need to focus on the business logic and nothing else.
- Create New Order Lambda is configured with AWS SQS as trigger point. AWS Lambda service does a Long Poling on the SQS and if there are items to be processed, it sends the items to the New Order Lambda for processing. By default, Lambda service reads items from SQS in batch of 5 with every batch having x number of items where x is a configurable parameter.
- AWS Lambda automatically increases the number of batches to be read from the SQS to scale the processing of the items.
What we have just implemented is called as Saga Orchestrator Pattern. If you need more details on Sagas in Microservices, take a look at below blog.
Sagas in Microservices
Everyone is doing Microservices and they just love it. Yes, I am serious, people are loving it. But to be honest…
Well, Team O is happy; they could implement the New Order flow by following 2 patterns —
- Adding Asynchronous event submission flow between API Gateway and New Order Microservice Lambda.
- Using Saga Orchestrator Pattern for handling long running business flow for New Order Creation — using AWS Serverless service Step Functions.
Their happiness could not last for long though — Why? They happened to discuss the flow with one of the other teams, who mentioned — We could have easily handled the long running flow using Choreograph Pattern for Saga, which is pretty smart pattern.
Also, Team O has one more question — how do we implement the use case of — Display Order status to the end user until the Order is delivered to them?
We will address both of the above point in the upcoming Part #3 of the blog.
Till then. Cheers!!!