- Service
Registry and Discovery:
- Pattern: Service Discovery
- Description: A service registry is used
to keep track of the available microservices and their locations.
Services register themselves with the registry, and clients can discover
and communicate with services through the registry.
- Benefits: Enables dynamic scaling and
seamless service discovery.
- API
Gateway:
- Pattern: API Gateway
- Description: An API Gateway acts as a
single entry point for managing requests from clients. It can handle
tasks such as authentication, authorization, and request routing to
different microservices.
- Benefits: Simplifies client
communication and provides a centralized point for managing cross-cutting
concerns.
- Circuit
Breaker:
- Pattern: Circuit Breaker
- Description: Introduces a circuit breaker
mechanism to prevent a microservice from repeatedly attempting to execute
an operation that is likely to fail. If the failure rate exceeds a
threshold, the circuit breaker opens, preventing further attempts until
the system stabilizes.
- Benefits: Improves system resilience
by avoiding cascading failures.
- Event
Sourcing:
- Pattern: Event Sourcing
- Description: Instead of storing only the
current state of data, all changes to the state are captured as a
sequence of events. The system's state can be reconstructed at any point
by replaying the events.
- Benefits: Provides a reliable audit
trail, supports scalability, and allows for building event-driven
architectures.
- Saga
Pattern:
- Pattern: Saga Pattern
- Description: Manages distributed
transactions across multiple microservices by breaking them into a series
of smaller, independent transactions (sagas). Each saga has its own
compensating transactions to handle failures and ensure eventual
consistency.
- Benefits: Enables long-running
business transactions in a distributed environment.
- Bulkhead
Pattern:
- Pattern: Bulkhead Pattern
- Description: Segregates components into
isolated pools to prevent the failure of one component from affecting
others. For example, thread pools can be used to isolate requests to a
specific microservice.
- Benefits: Enhances system resilience
by isolating failures and limiting their impact.
- Choreography
vs. Orchestration:
- Pattern: Choreography and
Orchestration
- Description: Defines how microservices
collaborate to achieve a specific goal. Choreography is a decentralized
approach where each service communicates directly with others.
Orchestration is a centralized approach where a central component
(orchestrator) coordinates the interactions.
- Benefits: Flexibility with
choreography and centralized control with orchestration.
- Polyglot
Persistence:
- Pattern: Polyglot Persistence
- Description: Recommends using different
data storage technologies for different microservices based on the
specific data requirements of each service.
- Benefits: Optimizes data storage
choices for individual microservices.
- Cross-Cutting
Concerns:
- Pattern: Microservices Centralized
Configuration
- Description: Manages cross-cutting
concerns such as logging, monitoring, and configuration in a centralized
manner to ensure consistency across microservices.
- Benefits: Simplifies management and
ensures uniformity of concerns.
These
patterns provide solutions to common challenges in microservices architecture,
promoting scalability, resilience, and maintainability in distributed systems.
Depending on specific use cases, additional patterns and variations may be
applied.
Here
are some common database patterns associated with microservices:
- Database
per Service:
- Pattern: Database per Service
- Description: Each microservice has its
own dedicated database. Microservices communicate with each other through
well-defined APIs, and each service is responsible for its own data
storage and retrieval.
- Benefits: Provides strong isolation
between microservices, allowing them to choose the most suitable database
technology for their specific needs.
- Shared
Database:
- Pattern: Shared Database
- Description: Multiple microservices share
a common database. This pattern is often seen in legacy systems, but it
can lead to tight coupling between services and hinder independent
development and scaling.
- Considerations: Can create dependencies
between services and make it challenging to evolve or scale
independently.
- API
Composition:
- Pattern: API Composition
- Description: Instead of relying on a
single microservice to fetch and aggregate data from multiple sources,
each microservice retrieves and composes its own data through API calls.
This pattern helps maintain independence and scalability.
- Benefits: Reduces dependencies between
microservices, allowing them to evolve independently.
- CQRS
(Command Query Responsibility Segregation):
- Pattern: CQRS
- Description: Separates the read and write
operations of a system. Commands (updates) and queries (reads) are
handled by different components, often with separate databases optimized
for their respective operations.
- Benefits: Optimizes performance for
read and write operations independently and allows for scalability based
on different usage patterns.
- Database
Sharding:
- Pattern: Database Sharding
- Description: Divides a large database
into smaller, more manageable pieces (shards) based on certain criteria.
Each shard can be hosted on a separate server or cluster.
- Benefits: Improves scalability by
distributing data across multiple servers, reducing the load on a single
database.
- Read
Replicas:
- Pattern: Read Replicas
- Description: For microservices with heavy
read workloads, create read-only replicas of the database to handle read
requests. The replicas can be distributed geographically to improve
performance.
- Benefits: Enhances read scalability
and offloads read operations from the primary database.
Choosing
the right database pattern for each microservice depends on factors such as
data consistency requirements, scalability needs, and the specific use cases of
each service. It's common to use a combination of these patterns within a
microservices architecture based on the characteristics of individual services.
Aggregator Pattern
Problem
We have talked about resolving the aggregating data problem in the API Gateway Pattern. However, we will talk about it here holistically. When breaking the business functionality into several smaller logical pieces of code, it becomes necessary to think about how to collaborate the data returned by each service. This responsibility cannot be left with the consumer, as then it might need to understand the internal implementation of the producer application.
Solution
The Aggregator pattern helps to address this. It talks about how we can aggregate the data from different services and then send the final response to the consumer. This can be done in two ways:
1. A composite microservice will make calls to all the required microservices, consolidate the data, and transform the data before sending back.
2. An API Gateway can also partition the request to multiple microservices and aggregate the data before sending it to the consumer.
It is recommended if any business logic is to be applied, then choose a composite microservice. Otherwise, the API Gateway is the established solution.
This pattern can be useful when a developer seeks an output by combining data from multiple services.
If there are two services, each with its own database, an aggregator with a unique transaction ID can collect data from each, apply the business logic, and publish it as a REST endpoint. Then, the data collected can be handed over to whichever respective microservices require it.
Blue-Green Deployment Pattern
Problem
With microservice architecture, one application can have many microservices. If we stop all the services then deploy an enhanced version, the downtime will be huge and can impact the business. Also, the rollback will be a nightmare. How do we avoid or reduce downtime of the services during deployment?
Solution
The blue-green deployment strategy can be implemented to reduce or remove downtime. It achieves this by running two identical production environments, Blue and Green. Let's assume Green is the existing live instance and Blue is the new version of the application. At any time, only one of the environments is live, with the live environment serving all production traffic. All cloud platforms provide options for implementing a blue-green deployment.
There are many other patterns used with microservice architecture, like Sidecar, Chained Microservice, Branch Microservice, Event Sourcing Pattern, Continuous Delivery Patterns, and more. The list keeps growing as we get more experience with microservices. I am stopping now to hear back from you on what microservice patterns you are using.