Microservices driven Architecture

Prashant Talele
5 min readFeb 21, 2021

“Microservice Architecture” has attracted a lot of attention in the last few years. It focuses more on modularity and Domain-driven design. In short, it's a variant of Service-oriented architecture(SOA). In this article, I am going to talk about what is Microservice-driven architecture, design patterns for well-defined Microservice architecture, and the pros and cons of this evolutionary design.

What is Microservices?

There is no single definition for microservices or I can say definition evolved over period Industry made a progress on digitization. It's an architectural style of defining service interfaces around business capabilities and domains.

Microservice architecture is an architectural style that structures an application as a collection of services that are

  • Highly maintainable and testable (Modular)
  • Loosely coupled (Scalable, Isolable)
  • Independently deployable (easy Integration)
  • Organized around business capabilities (Domain driven)
  • Owned by a small product team (Complete ownership)

Business Processes/Products are composed of multiple application components. Each application component includes entities, operations, and complex interactions. Microservices provide a way to develop these operations and interactions in a highly maintainable and testable, loosely coupled, independently deployable manner.

Here is how simple Microservice driven architecture looks like -

Design Patterns for Microservice architecture

  1. Decompose by business domain

Define services corresponding to Domain-Driven Design (DDD) subdomains.

Subdomains can be classified as :

  • Core — key differentiator for the business and the most valuable part of the application
  • Supporting — related to what the business does but not a differentiator. These can be implemented in-house or outsourced.
  • Generic — not specific to the business and are ideally implemented using off the shelf software

2. Self-contained service

Design the service so that it can respond to a synchronous request without waiting for a response from any other service.

A self-contained Microservice collaborates with other services using the CQRS and the Saga patterns. A self-contained service uses the Saga pattern to asynchronously maintain data consistency. It uses the CQRS pattern to maintain a replica of data owned by other services.

3. Service per team

To enables each team to be autonomous and work with minimal coordination with other teams, it's a good idea to have complete ownership of service per team. It also improves code quality due to long term code ownership.

4. Strangler Application

Strangler pattern enables modernize an application by incrementally developing a new application around the legacy application. The strangler application consists of two types of services. First, there are services that implement functionality that previously resided in the monolith. Second, there are services that implement new features.

5. Anti-corruption Layer

To prevent a legacy monolith’s domain model from polluting the domain model of a new service, define an anti-corruption layer, which translates between the two domain models.

6. Database per Service

The goal of microservice architecture is to define loosely coupled services so that they can be developed, deployed, and scaled independently.

As services need to persist data in the database, keep each microservice’s persistent data private to that service and accessible only via its API. A service’s transactions only involve its database.

7. Saga

Implement each business transaction that spans multiple services as a saga. A saga is a sequence of local transactions. Each local transaction updates the database and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails because it violates a business rule then the saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions.

8. Command Query Responsibility Segregation (CQRS)

As Microservice stress on database per service, implementing a query that retrieves data from multiple services in a microservice architecture becomes tricky. This problem is solved by CQRS pattern by defining a view database, which is a read-only replica that is designed to support that query. The application keeps the replica up to date by subscribing to domain events published by the service that owns the data.

9. Domain Events

Each microservice participating in saga publish a set of events when data is updated. Organize the business logic of a service as a collection of domain events. The service publishes these domain events so that they can be consumed by other services.

10. Event Sourcing

A service command typically needs to update the database and send messages/events. Microservices implement an event-driven architecture and makes it possible to reliably publish events whenever state changes. Events are persisted to audit domain entities.

Event Sourcing enables loosely coupled business entities that exchange events to make it easier to migrate from a legacy application to a microservice architecture.

Benefits

· Modularity more resilient to architecture erosion as compared to the complexity of monolithic architectures

· Scalability deployed, monitored, and scaled independently

· Isolation problems in 1 service do not impact other services.

· Distributed Development parallelizes development by enabling small autonomous teams to develop, deploy and scale their respective services independently.

· Improved Fault Tolerance

· Better Testability as services are smaller and faster to test

Disadvantages

Microservice Architecture has a number of drawbacks:

  • Developers must deal with the additional complexity of creating a distributed system:
  • Developers must implement the inter-service communication mechanism and deal with partial failure
  • Implementing requests that span multiple services is more difficult
  • Testing the interactions between services is more difficult
  • Implementing requests that span multiple services requires careful coordination between the teams
  • Deployment complexity In production, there is also the operational complexity of deploying and managing a system comprised of many different services.
  • Increased memory consumption. The microservice architecture replaces monolithic application instances with multiple service instances, each service runs in its own JVM, which is usually necessary to isolate the instances, then there is the overhead of many JVM runtimes. Moreover, if each service runs on its own VM (e.g. EC2 instance), the overhead is even higher.

References

--

--

Prashant Talele

Strategic Contributor and highly motivated leader with over 17+ years of experience strengthening Software delivery process to build high quality products.