Add a messaging component to reduce coupling between microservices

Messaging system for microservices

Two approaches to tackle a problem in software development

1. Divide and Conquer

2. Loose coupling

We are already following divide and conquer when we are following microservices architecture and most people follow this, however next step of adding loose coupling between systems gets missed

When few microservices are interacting with each other without a messaging queue component, they are tightly coupled and are not fault-tolerant as a system, this synchronous nature where the API must respond to request immediately is difficult to scale as well, so kind of bug for a system as a whole

A good way to apply loose coupling is through adding a messaging system, which is the focus of this post

There are two types of messaging service that can be implemented between microservices

a. queue, where messages/requests will be queued and next available system will consume request from queue one at a time, thus queue acts as a buffering load balancer

It further has two types

i. fire and forget, the sender does not need acknowledgement

ii. the sender sends additional metadata to get acknowledged on successful capture of a message

b. Topic, where each available system/subscriber is expected to receive all the messages, which subscriber has subscribed to, so we can understand that it is not a very scalable solution

Best messaging system would be a combination of both queue and topic, so messages will be queued and then diverted to the subscribed system

The AWS services offering messaging services are

SQS (Simple Queue Service) which is a Queue implementation

SNS (Simple Notification Service) which is a Topic implementation

Now, we can talk about Dead Letter Queue, which acts as bug removing system in messaging system

When if the message after being processed by system gets rejected due to exception and put back into the queue, the message will again be read by the system to be processed again, and if this process repeats, it is poisoning the system, so such messages which fail a threshold times are diverted to another queue, which is Dead letter Queue and now, this messages can be analysed for the cause of exceptions.

a. Standard SQS: which has high throughput, following best-effort ordering, more than one copy of a message might be delivered out of order

b. FIFO SQS: which offers reduced throughput, due to synchronous processing, but since message order is strictly preserved it is useful in scenarios like payments, where you want an order to be processed after payment is completed

FIFO SQS uses message group id so that at one time, only one message of a particular group id will be processed

side note: System should be designed idempotent so that system state remains same on repeated consumption of a particular message

Another feature in the messaging system is recipient list, where sender maintains a list of subscribers, but it again introduces tight coupling, so topic, where, subscribers subscribe to certain topics is preferred

Now lets study Messaging system with Saga Pattern

saga: a sequence of the local transactions,

1. each service in saga performs its own transaction and publishes an event

2. other service listens to its own subscribed event and performs next local transaction

these are event-driven without tight coupling

The base of saga pattern is orchestrator component, in which we define the workflows (i.e. processing steps), thus system remains loosely coupled

orchestrator allows us to implement branching, read/write and parallel processing for workflows

Saga pattern can be implemented by creating state machines with AWS step function

Let me know your views!

Based on AWS May 2020 Online Summit, Application integration patterns for microservices (level 300)

I love learning