Tuesday, December 31, 2019

Microservice Architecture Design patterns


What are Microservices?
Microservices is an architectural style that structures an application as a collection of small autonomous services, modeled around a business domain. In a Microservice Architecture, each service is self-contained and implements a single business capability.
Principles Used to Design Microservice Architecture
The principles used to design Microservices are as follows:
1.    Independent & Autonomous Services
2.    Scalability
3.    Decentralization
4.    Resilient Services
5.    Real-Time Load Balancing
6.    Availability
7.    Continuous delivery through DevOps Integration
8.    Seamless API Integration and Continuous Monitoring
9.    Isolation from Failures
10. Auto -Provisioning







Application architecture patterns
  • Monolithic architecture
  • Microservice architecture

Decomposition

Refactoring to microservices

Data management
Transactional messaging
  • Transactional outbox
  • Transaction log tailing
  • Polling publisher
Testing
  • Service Component Test
  • Consumer-driven contract test
  • Consumer-side contract test
Deployment patterns
  • Multiple service instances per host
  • Service instance per host
  • Service instance per VM
  • Service instance per Container
  • Serverless deployment
  • Service deployment platform
Cross cutting concerns
Communication style
  • Remote Procedure Invocation
  • Messaging
  • Domain-specific protocol
External API
  • Client-side discovery
  • Server-side discovery
  • Service registry
  • Self registration
  • 3rd party registration
Reliability
Security
  • Access Token
Observability
UI patterns
Microservices architecture involves designing and building a software system as a collection of small, independent, and loosely coupled services. Various design patterns have emerged to address common challenges associated with building and maintaining microservices-based systems. Here are some key microservices design patterns:
  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.


No comments:

Post a Comment