🧩 Microservices Design Patterns

1. Decomposition Patterns

  • By Business Capability β†’ Services align with domain areas (e.g., Payments, Orders, Inventory).
  • By Subdomain (DDD) β†’ Use Domain-Driven Design to identify bounded contexts.
  • Strangler Fig Pattern β†’ Gradually replace monolith pieces with microservices.

2. Integration Patterns

  • API Gateway β†’ Single entry point for clients, routes to services.
  • Aggregator β†’ One service calls multiple others and aggregates results.
  • Proxy β†’ Gateway just forwards requests, adds security, throttling.
  • Chained Service Calls β†’ Service β†’ Service β†’ Service (can get risky with latency).
  • Asynchronous Messaging β†’ Use queues/events (Kafka, RabbitMQ) to decouple services.

3. Database Patterns

  • Database per Service β†’ Each service owns its data (most common).
  • Shared Database β†’ Multiple services share one DB (not recommended, but sometimes practical).
  • Saga Pattern β†’ Distributed transaction management via events/compensating actions.
  • CQRS (Command Query Responsibility Segregation) β†’ Separate read/write models for performance.
  • Event Sourcing β†’ Store state as a series of events instead of just final state.

4. Observability Patterns

  • Log Aggregation β†’ Centralized logs (ELK, Loki).
  • Distributed Tracing β†’ Trace requests across services (Jaeger, Zipkin, Tempo).
  • Health Check API β†’ Each service exposes /health for monitoring.
  • Metrics Aggregation β†’ Collect metrics (Prometheus + Grafana).

5. Resiliency Patterns

  • Circuit Breaker β†’ Stop calls to failing service (e.g., Resilience4j, Hystrix).
  • Retry Pattern β†’ Retry failed calls with backoff.
  • Timeout Pattern β†’ Don’t let one service hang others.
  • Bulkhead β†’ Isolate failures so one service doesn’t crash the system.
  • Fail-Fast β†’ Quickly reject if downstream is not available.
  • Fallback β†’ Provide default response when service fails.

6. Security Patterns

  • Access Token (JWT, OAuth2) β†’ Secure service-to-service & client calls.
  • API Gateway Authentication β†’ Central place for auth.
  • Service Mesh (Istio, Linkerd) β†’ Handles mTLS, auth, rate limiting at infra level.

7. Deployment Patterns

  • Blue-Green Deployment β†’ Switch traffic between two environments.
  • Canary Release β†’ Gradually roll out new versions.
  • Sidecar Pattern β†’ Extra container alongside a service (e.g., Envoy proxy).
  • Service Mesh β†’ Offload cross-cutting concerns (security, retries, tracing).

βœ… These patterns are often combined in real-world microservices systems depending on business needs, scalability, and reliability.


βš“ Bulkhead Pattern (Resiliency)

πŸ“Œ What It Is

The Bulkhead pattern is a resiliency design pattern that isolates failures in a system so that when one part fails, it doesn’t bring down everything else.

It’s inspired by ships:

  • A ship has bulkheads (partitions) so if one compartment floods, the others stay safe.
  • Similarly, in microservices, you isolate resources so a failure in one area won’t sink the entire system.

πŸ›  How It Works

  • Allocate separate resources (threads, DB connections, memory pools) per service or per feature.
  • If one service gets overloaded, it only consumes its own quota, not the entire pool.
  • Prevents a β€œnoisy neighbor” problem where one service hogs resources and starves others.

βœ… Example

Imagine an e-commerce app with:

  • Payment Service
  • Order Service
  • Notification Service

If the Payment Service suddenly gets slow (maybe the bank API is lagging):

  • Without bulkhead β†’ all system threads are stuck waiting, and Orders + Notifications also fail.
  • With bulkhead β†’ only the Payment Service’s thread pool is affected, Orders + Notifications still work.

πŸ”§ Implementation Approaches

  • Thread pool per service β†’ Each service gets its own threads.
  • Connection pool isolation β†’ Separate DB connections per microservice.
  • Rate limiting per service β†’ Prevent one service from exhausting shared resources.
  • With Circuit Breaker β†’ Often combined: bulkhead isolates, circuit breaker stops repeated failures.

πŸ“Š Tools & Frameworks

  • Java / Spring Boot β†’ Use Resilience4j bulkhead module (BulkheadRegistry).
  • .NET β†’ Polly provides bulkhead policies.
  • Service Mesh (Istio/Linkerd) β†’ Can enforce isolation & limits at infra level.

πŸ‘‰ In short: Bulkhead = Contain the blast radius of a failure.


⚑ Circuit Breaker (Microservices)

Definition Circuit Breaker is a resiliency pattern that stops calling a failing service to prevent cascading failures and system overload.


πŸ” How It Works (States)

  1. Closed

    • Normal operation
    • Requests flow
    • Failures are monitored
  2. Open

    • Too many failures detected
    • Calls are blocked immediately
    • Fallback response is returned
  3. Half-Open

    • After wait time
    • Allows few test requests
    • If success β†’ back to Closed
    • If failure β†’ back to Open

🎯 Why Use It

  • Prevents system overload
  • Avoids cascading failures
  • Improves response time
  • Enables graceful degradation

πŸ“Œ Example

Order Service β†’ calls β†’ Payment Service

If Payment Service is down:

  • Without circuit breaker β†’ Order service keeps retrying β†’ thread pool exhausted
  • With circuit breaker β†’ calls blocked β†’ instant fallback β†’ system stays stable

πŸ”§ Implementation

@CircuitBreaker(name = "paymentCB", fallbackMethod = "fallback")
public String pay() {
    return paymentClient.call();
}

public String fallback(Exception e) {
    return "Payment service unavailable";
}

  • Resilience4j (Java)
  • Hystrix (Deprecated)
  • Polly (.NET)
  • Istio / Service Mesh (infra level)

πŸ‘‰ In Short

Circuit Breaker = Fail fast + protect system + auto recovery