Microservice is a single application in a suite of small services. Each microservice communicates via a lightweight protocol e.g HTTP, Message Queues. In accordance with the database per service pattern, each of them has its own database. They must communicate with each other in order to access others data.
Basically, there are two patterns that microservices can use to talk to each other.
In this communication, a microservice communicates via another microservice’s API endpoint and waits for its response. The call will be blocked until the response is received. It’s easy to understand and implement but it comes with its own drawbacks e.g high latency, downtime, etc.
A microservice sends a message to another microservice via a message queue and does not wait for the response. It’s a non-blocking call. There are a lot of benefits of implementing the asynchronous pattern. Let’s discuss some of them here.
Benefits of using Asynchronous Communication
A sender does not need to know about the receiver interface. They can communicate via standard message queues. It increases decoupling in code.
In asynchronous communication, microservices communicate via message queues. The message can be consumed by multiple subscribers using the publisher/subscribers model.
When a microservice goes down, the other microservices can do their work and write messages onto the queue. The failed microservice can read them whenever it will be up and running. The message queues ensure fault tolerance and message reliability.
Response time will be reduced much if we do the bare minimum work synchronously in the HTTP call sent by the client and do the rest asynchronously and notify the client about the updates.
Drawbacks of Asyncrhonous Communication
Coupling with Message Infrastructure
Since we use message queues a lot in asynchronous communication, there is a high chance that our code can be coupled with message infrastructure.
Handling asynchronous messages is quite complex. We need to deal with duplicated messages and make the request idempotent. We must identify the cost of consuming multiple messages. There are multiple patterns of handling messages e.g at least one message, at most one message, and only one message.
Dealing with transactions in asynchronous communication is a huge topic to discuss on its own. What if something fails in the transaction then how we can revert the transaction.
To conclude, there is always a tradeoff when we use any pattern. We must identify systems requirements and choose based on them.