Microservices
How it works
- Define bounded contexts
- Database per service
- Asynchronous integration
- Observability and SLOs
🎯 What are Microservices?
Microservices architecture breaks down a large application into small, independent services that communicate over well-defined APIs. Each service is like a mini-application with a specific function.🛠️ Service A
🛠️ Service B
🛠️ Service C
⬇️
🌐 API Gateway
Overview
- Decompose by business capability; services are independently deployable and own their data.
- Emphasizes loose coupling, high cohesion, and explicit contracts.
When to use
- Teams are large and need independent delivery cadences.
- Product domains are well-understood with clear bounded contexts.
- You need selective scalability and fault isolation.
Trade-offs
- Higher operational overhead: CI/CD, infra, observability, and platform.
- Distributed failure modes: retries, timeouts, partial failures.
- Data consistency becomes an architectural concern.
Patterns
- API Gateway + Service discovery + mTLS.
- Database-per-service; use the Outbox + Saga for cross-service transactions.
- Event-driven choreography; idempotent consumers.
Anti-patterns
- “Microservices first” for an unclear domain; premature decomposition.
- Shared database across services coupling schemas and deploys.
- Chatty synchronous calls forming a distributed monolith.
📐 Quick Diagram
Client ▶ API Gateway ▶ Auth │ Users │ Orders │ Inventory
│ events └────────▶ Kafka ▶ Consumers
❓ Interview Q&A (concise)
- Q: Split by technical layers or business capability? A: Business capability; avoid CRUD-by-table services.
- Q: Handle distributed transactions? A: Saga + Outbox; compensate on failure instead of 2PC.
- Q: Reduce latency? A: Coarse APIs, cache, async patterns, and avoid N+1 downstream calls.
🏗️ Characteristics
- Business Capability Focus: Each service handles a specific business function
- Decentralized: Independent deployment and scaling
- Technology Agnostic: Services can use different technologies
- Fault Isolation: Failure in one service doesn't bring down others
- Independent Teams: Teams can work autonomously
🚀 Benefits
- Scalability: Scale individual services based on demand
- Technology Diversity: Use best tool for each job
- Fault Tolerance: Isolate failures
- Team Independence: Faster development cycles
- Easier Maintenance: Smaller, focused codebases
⚠️ Challenges
- Distributed System Complexity: Network calls, latency, failures
- Data Consistency: Managing transactions across services
- Service Discovery: Finding and communicating with services
- Monitoring: Tracking requests across multiple services
- Testing: Integration testing becomes complex
🛠️ Design Patterns
Service Communication
- Synchronous: REST APIs, GraphQL
- Asynchronous: Message queues, event streaming
Data Management
- Database per Service: Each service owns its data
- Saga Pattern: Manage distributed transactions
- CQRS: Separate read and write models
Reliability Patterns
- Circuit Breaker: Prevent cascade failures
- Bulkhead: Isolate resources
- Timeout: Prevent hanging requests
🔄 Migration Strategy
- Strangler Fig Pattern: Gradually replace monolith
- Database Decomposition: Separate data first
- API Gateway: Single entry point for clients
- Service Mesh: Handle cross-cutting concerns