Microservices are an architectural and organizational approach to software development where software is composed of small independent services that communicate over well-defined APIs. Each module supports a specific task or business goal and uses a simple, well-defined interface, such as an application programming interface (API), to communicate with other sets of services. In a microservices architecture, an application is divided into services. Each service runs a unique process and usually manages its own database. Microservices architectures make applications easier to scale and faster to develop and accelerate time-to-market for new features.
In a distributed architecture, components are presented on different platforms, and several components can cooperate with one another over a communication network to achieve a specific objective or goal. Three significant characteristics of distributed systems are the concurrency of components, lack of a global clock, and independent failure of components. It deals with a central challenge that, when components of a system fail, it doesn't imply that the entire system fails.
Distributed Data Management in Microservices
When developing microservices, we must tackle the problem of distributed data management. Each microservice has its own private database, sometimes a SQL and sometimes a NoSQL database. Developing business transactions that update entities that are owned by multiple services is a challenge, as is implementing queries that retrieve data from multiple services.
Data access becomes much more complex when we move to a microservices architecture. That is because the data owned by each microservice is private to that microservice and can only be accessed via its API. If multiple services access the same data, schema updates require time‑consuming, coordinated updates to all the services.
Another major issue with microservices is network failure. If any service is down due to a network issue or any other reason, then one service cannot communicate with other, and the entire transaction will be failed. For example, Service A is trying to communicate with Service B where B is already down, then the transaction fails.
Why Event-Driven Architecture?
For most applications, the way to make microservices work and to manage distributed data successfully is to adopt an event-driven architecture. There are various patterns available, and we are going to concentrate on the very first pattern called Event Messaging.
Event-Driven Architecture is called as a messaging system. A message is simply an event, or vice versa, an event becomes a message. The concept of an event-driven system is that it should cause everything that is interested to be notified of these events that could benefit from knowing about it. Events can be used to implement business transactions that span multiple services, which give you eventual consistency between those services. An eventually consistent transaction consists of a series of distributed actions. At each action, the microservice updates a business entity and publishes an event that triggers the next action. Thus, the earliest real-time event-driven systems came up with the notion of publish/subscribe.
The concept of an event-driven system is that it should cause everything that is interested to be notified of these events that could benefit from knowing about it.
Publish/subscribe is another way to describe event-oriented messaging. In the publish/subscribe paradigm, there are publishers and subscribers. A publisher does not need to know anything about the subscribers of the information they are publishing to other than that they are entitled to receive the information. Similarly, the subscriber does not need to know anything about the publisher other than that they are authenticated to be a legitimate publisher.
A pub/sub system should support a mechanism for publishers to find out about new subscribers, and subscribers should be able to find the publishers of information immediately upon their availability.
As a subscriber, you would need to know that you can be guaranteed to receive all messages from the publishers in the time sequence they occurred if desired (reliability and security). All subscribers should be notified of the event as close to the same time as possible.
Message Broker act as a key mediator between publisher and subscriber. The purpose of a broker is to take incoming messages from applications and make them available for the subscriber to fetch the messages. The messages will be retained by the broker until it is fetched by the corresponding subscribers. The most popular message brokers are Apache Kafka, Apache ActiveMQ, RabbitMQ etc.
The important features of event-driven systems are asynchronous behaviour and loosely coupled structures. For example, instead of requesting data when needed, apps consume them via events before the need. Therefore, overall app performance increases. Keeping coupling loose is one of the main key points of a microservice environment.
Benefits of the Event-Driven Microservice Architecture
- Loosely coupled structure
- Complete isolation of the microservices
- No synchronous REST calls
- Asynchronous event-driven functionality
- Performance gain
In this blog post, we discussed the challenges of Distributed data management in Microservices and how Event-Driven architecture helps to address these issues using Event Messaging patterns.