Microservices Architecture Patterns
Design, build, and deploy microservices at scale with Kubernetes, Docker, and service mesh patterns.
What You'll Learn
- • Core microservices design patterns and principles
- • Service decomposition strategies and domain boundaries
- • API gateway patterns and inter-service communication
- • Data consistency and distributed transaction patterns
- • Kubernetes deployment and service mesh integration
- • Monitoring, observability, and troubleshooting strategies
Introduction to Microservices Architecture
Microservices architecture decomposes applications into independent, loosely coupled services that communicate over well-defined APIs. This approach enables teams to develop, deploy, and scale services independently, resulting in improved agility, fault isolation, and technology diversity.
Core Principles
- Single Responsibility: Each service focuses on a specific business capability
- Decentralized: Services own their data and business logic
- Fault Tolerant: Services handle failures gracefully without cascading
- Observable: Comprehensive monitoring and logging across services
Service Decomposition Strategies
Domain-Driven Design (DDD) Approach
// Example: E-commerce domain boundaries
User Service:
- User authentication and profiles
- User preferences and settings
Product Catalog Service:
- Product information and search
- Inventory management
Order Service:
- Order processing and workflow
- Order history and tracking
Payment Service:
- Payment processing
- Transaction history
Notification Service:
- Email and SMS notifications
- Push notificationsDecomposition Patterns
By Business Capability
Organize services around business functions like user management, order processing, or inventory.
By Data Ownership
Each service owns its data and provides APIs for other services to access it.
Inter-Service Communication Patterns
Synchronous Communication
# API Gateway Configuration (Kubernetes Ingress)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-gateway
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: api.example.com
http:
paths:
- path: /users/(.*)
pathType: Prefix
backend:
service:
name: user-service
port:
number: 80
- path: /orders/(.*)
pathType: Prefix
backend:
service:
name: order-service
port:
number: 80Asynchronous Communication
# Event-Driven Architecture with Kafka
version: '3.8'
services:
kafka:
image: confluentinc/cp-kafka:latest
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
order-service:
image: order-service:latest
environment:
KAFKA_BROKERS: kafka:9092
EVENT_TOPICS: order-created,order-updated,order-cancelled
depends_on:
- kafka
notification-service:
image: notification-service:latest
environment:
KAFKA_BROKERS: kafka:9092
SUBSCRIBED_TOPICS: order-created,order-updated
depends_on:
- kafkaData Management Patterns
Database per Service
Each microservice should have its own database to ensure loose coupling and independent evolution.
# Docker Compose with Separate Databases
version: '3.8'
services:
user-service:
image: user-service:latest
environment:
DB_HOST: user-db
DB_NAME: users
depends_on:
- user-db
user-db:
image: postgres:15
environment:
POSTGRES_DB: users
POSTGRES_USER: userservice
POSTGRES_PASSWORD: userpass
volumes:
- user_data:/var/lib/postgresql/data
order-service:
image: order-service:latest
environment:
DB_HOST: order-db
DB_NAME: orders
depends_on:
- order-db
order-db:
image: postgres:15
environment:
POSTGRES_DB: orders
POSTGRES_USER: orderservice
POSTGRES_PASSWORD: orderpass
volumes:
- order_data:/var/lib/postgresql/data
volumes:
user_data:
order_data:Saga Pattern for Distributed Transactions
Handle distributed transactions using the Saga pattern, which manages data consistency across services through choreography or orchestration.
Kubernetes Deployment Patterns
Service Deployment
# Microservice Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
labels:
app: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:v1.0.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "user-db-service"
- name: KAFKA_BROKERS
value: "kafka-service:9092"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080
type: ClusterIPService Mesh with Istio
# Istio VirtualService for Traffic Management
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- match:
- headers:
version:
exact: v2
route:
- destination:
host: user-service
subset: v2
weight: 100
- route:
- destination:
host: user-service
subset: v1
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: user-service
spec:
host: user-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2Monitoring and Observability
The Three Pillars of Observability
Metrics
Prometheus + Grafana for collecting and visualizing performance metrics.
Logs
Centralized logging with ELK stack (Elasticsearch, Logstash, Kibana).
Traces
Distributed tracing with Jaeger or Zipkin for request flow analysis.
Prometheus Monitoring Setup
# Prometheus ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)Production-Ready Configurations
Best Practices and Common Pitfalls
Best Practices
- • Start with a monolith and decompose gradually
- • Design for failure with circuit breakers and retries
- • Implement comprehensive monitoring and alerting
- • Use API versioning for backward compatibility
- • Automate testing across service boundaries
- • Implement proper security between services
Common Pitfalls to Avoid
- • Creating too many services too early (nano-services)
- • Sharing databases between services
- • Synchronous communication everywhere
- • Neglecting network latency and failure scenarios
- • Inconsistent logging and monitoring
- • Ignoring data consistency patterns