Interaction between microservices

The next question that comes to mind when I figured out how to work with data in this architecture (or maybe for someone this question is the first one) is How will microservices interact with each other?

Basic approaches to microservices interaction

Synchronous interaction

Let's look at some of the advantages:

  • There are several interesting advantages to the synchronous interaction approach, such as simplicity. HTTP requests of this kind are easy to understand and use, since they are essentially a standard client-server model.

  • In synchronous systems, it is easier to implement transactions at the level of interaction between services, since operations are performed sequentially and return a response immediately.

  • In systems with minimal performance requirements and low latency, the synchronous approach is effective because it allows immediate results.

In addition to the above-described advantages, we also have the following disadvantages:

  • The interaction becomes vulnerable to temporary service unavailability. If one microservice is unresponsive, it can block the entire call chain. (There will be an example below that solves this problem)

  • Each request in a synchronous interaction requires a network request and a wait for a response, which can cause high latencies, especially if the interaction occurs over the Internet or in distributed systems with high latency. (In network technologies latency – a delay or wait that increases the actual response time compared to the expected one).

  • Synchronous calls block the thread until a response is received, making them less efficient under high loads. The inability to process requests in parallel increases the load on resources.

  • If one of the microservices fails, the system may freeze, since synchronous interaction involves waiting for the request to complete.

Methods of interaction:

Asynchronous communication

Advantages:

  1. Asynchronous communication allows microservices to process requests and events independently of the response time of other services. This reduces blocking (In fact, this solves the problem of vulnerability to temporary unavailability of services.) and allows the system to handle heavy loads.

    This directly impacts performance if you have a large system.

  2. Reduced coupling between microservices. In this case, microservices do not directly depend on each other to respond immediately.

  3. Using message brokers or an event-driven model allows systems to easily work with real-time data streams, such as IoT event processing, logging, and analytics.

  4. If one of the services is temporarily unavailable, the system continues to operate because requests can accumulate in a message queue and be processed when the service becomes available again.

In fact, this very interaction can be implemented using the following tools

  • Message via message brokers (Kafka, RabbitMQ, NATS, NSQ, etc.).

  • Event-driven approach.

Possible difficulties:

  1. Asynchronous systems are more difficult to develop and maintain because they require consideration of message order, reprocessing, and data consistency. But more often than not, such issues have to be addressed at the start of a project rather than once the understanding and vision of the project has been formed.

  2. Debugging and tracing become more difficult because requests may go through multiple services with latency and their processing order may vary.

  3. Additional logic is required to handle message loss, duplication, and sequencing. Mechanisms for acknowledging receipt and processing of messages, such as transactions, retries, and compensation actions, must be implemented.

  4. Using message brokers or event systems requires additional infrastructure and management, which can increase the complexity of maintenance and the cost of the system.

Challenges and Complexities in Inter-Microservice Communication

Network latency and fault tolerance
How to handle network failures and service unavailability?

  • Timeouts / Replays

  • Circuit Breaker (Pattern Fuse)

  • As I said earlier – asynchronous interaction

  • Duplication and replication of services to improve availability

  • Monitoring and alerts

  • Temporal load distribution (Distributing requests over time intervals (rate limiting) will help reduce the load on services, which reduces the likelihood of failure)

  • Graceful degradation
    Implementation of a degradation mode so that your services can continue to operate with limited functionality in the event of a failure of one of the system parts.

Transactionality
How to ensure data consistency (SAGA pattern)?

To find an answer to this question, I refer you, reader, to this article – The “saga” pattern as a way to ensure consistency

Safety
How to secure inter-microservice interactions (authentication, authorization, data encryption).

I won’t describe here how to implement different types of user authorization/authentication, an important question in the context of microservices is how to implement this very check of user authorization in the system?

There are 2 great articles on Habr as an answer to this question

Monitoring and tracing
What tools can be used to implement monitoring?

  • Prometheus is a monitoring and alerting system focused on time-series data. It is ideal for microservices due to its ability to collect metrics from containers and support queries via the PromQL query language.

  • Grafana is a powerful tool for visualizing metrics.

  • ELK Stack (Elasticsearch, Logstash, Kibana) – allows you to collect, store and analyze microservice logs. Logstash is used to collect and process logs, Elasticsearch for storage and search, and Kibana for data visualization, which simplifies the analysis of events and metrics.

  • Jaeger, Zipkin – a tracing system that helps track requests in distributed systems.

  • OpenTelemetry – is a set of tools and APIs that allows you to collect, process and export metrics, traces and logs data. It supports integration with various monitoring and tracing tools, making it a universal solution.

  • Datadog, New Relic – cloud service for monitoring and analytics.

Microservices Interaction Patterns

API Gateway
Centralize requests through a single access point.

For what?

Essentially the core component of your distributed system, facilitating efficient interaction between different services.

Here are the main reasons why API Gateway is necessary:

  • Centralized Entry Point and Routing Management – ​​serves as a single point of access for all client requests and is responsible for routing requests to the appropriate microservices.

  • Authentication and authorization – can perform access control functions, ensuring the security of microservices. The advantage of this approach is that it allows you to avoid duplicating the authentication code in each service.

  • Load limiting and DoS protection – can manage the load by imposing limits on the number of requests from the client.

  • Response consolidation – can aggregate data from multiple microservices and return it to the client in a single response.

  • Versioning – API versions can be managed, making it easier to update microservices and interact with clients that may be using different versions of the application.

Service Mesh
Controlling traffic between microservices.

You can read more about this pattern here – Service mesh use cases

Materials for study

  • Microservices

  • RabbitMQ

  • Apache Kafka

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *