Microservices — Basics
Microservices — Basics
Section titled “Microservices — Basics”What it is
Section titled “What it is”Architectural style: app split into small, independently deployable services around business capabilities. Each owns its data, exposes a contract (REST/gRPC/events), and runs in its own process.
When to use / avoid
Section titled “When to use / avoid”Use when:
- Multiple teams need independent deploy cadence.
- Different scaling profiles per component.
- Polyglot tech stacks justified.
- Fault isolation matters.
Avoid when:
- Small team / early-stage product. Start with modular monolith.
- Strong cross-entity transactions and reporting dominate.
- Operational maturity (CI/CD, observability, on-call) isn’t there yet.
Core principles
Section titled “Core principles”- Bounded context (DDD) — service owns one cohesive business concept.
- Database per service — no shared schema. Cross-service data via API or events.
- Smart endpoints, dumb pipes — logic in services, not in the message broker.
- Decentralized governance — teams choose tools within guardrails.
- Design for failure — every remote call can fail / time out.
- Contract-first — explicit, versioned API/event schemas.
Communication styles
Section titled “Communication styles”| Style | Examples | Use |
|---|---|---|
| Sync request-response | REST, gRPC | UI-driven, immediate result |
| Async messaging | Kafka, RabbitMQ, SQS, EventBridge | Decoupled workflows, long-running |
| Pub/sub events | Kafka, EventBridge, SNS | Fan-out, reactive systems |
| Streaming | gRPC streaming, Kafka, SSE, WebSocket | Continuous data |
Service discovery
Section titled “Service discovery”- Client-side: clients query a registry (Eureka, Consul) and load-balance themselves.
- Server-side: load balancer in front (K8s Service, ELB).
- DNS-based: simplest, K8s default.
Data management
Section titled “Data management”- Saga — distributed transaction as sequence of local txns + compensating actions.
- Outbox — write event to outbox table in same DB txn as state change; relay process publishes.
- CDC (change data capture) — Debezium reads DB log, emits events.
- CQRS — separate read and write models. Often pairs with event sourcing.
- Event sourcing — store events not state; rebuild state by replay.
Resiliency patterns
Section titled “Resiliency patterns”- Timeout — every external call must have one. Without it, you cascade.
- Retry — only on idempotent operations, with backoff + jitter.
- Circuit breaker — fail fast when downstream is unhealthy. Half-open to probe recovery.
- Bulkhead — isolate resources (thread pools / connection pools) per dependency to prevent one dependency starving the rest.
- Rate limit / load shed — protect yourself from overload.
- Idempotency keys — client-supplied id; server dedupes retries.
- Backpressure — slow producer when consumer can’t keep up.
API gateway
Section titled “API gateway”- Single entry point for clients. Auth, rate-limit, routing, response shaping, caching.
- Tools: Kong, Tyk, AWS API Gateway, Envoy, Nginx, Traefik.
Service mesh
Section titled “Service mesh”- Sidecar proxy (Envoy) per service. Handles mTLS, retries, timeouts, traffic shifting, observability — without app code.
- Tools: Istio, Linkerd, Consul Connect, AWS App Mesh.
Testing
Section titled “Testing”- Unit, integration (per service), contract (Pact), end-to-end (sparse, expensive).
- Consumer-driven contract — consumers state expectations; provider tested against them.
Deployment
Section titled “Deployment”- One service per pod / container.
- CI/CD per service. Independent versioning.
- Strategies: rolling, blue/green, canary, feature flags.
Observability — the trinity
Section titled “Observability — the trinity”- Logs (structured, correlated by trace_id).
- Metrics (RED: rate, errors, duration; USE: utilization, saturation, errors).
- Traces (distributed via OpenTelemetry).