Microservices Architecture
- Reading time
- 3 min read
- Word count
- 491 words
- Diagram count
- 0 diagrams
Source: Victor Bona's Obsidian Compendium snapshot, Knowledge base/Design Patterns/Microservices Architecture.md.
Microservices architecture is an architectural style where an application is structured as a collection of small, independently deployable services that communicate over a network (often via HTTP/REST or messaging). Each service typically owns its data (database) and handles a specific business capability. This contrasts with a monolithic architecture, where the entire application is one unified codebase and deployment.
-
Intent: Break down a large system into smaller services that can be developed, deployed, and scaled independently. Each microservice focuses on a single business capability and uses lightweight communication with others.
-
Characteristics:
- Services are autonomous: each can be updated or restarted without impacting others (as long as contracts/interfaces are maintained).
- Typically organized around business capabilities (e.g., an Order service, Inventory service, Payment service in an e-commerce system).
- Decentralized data management: each service manages its own database or data store (avoiding a single monolithic database schema).
- Decentralized governance and technology: different services could be written in different languages or use different storage, if appropriate (though teams often limit variety to reduce complexity).
- Communicate through lightweight mechanisms (often RESTful APIs, or async messaging).
- Designed for failure isolation: if one service fails, the whole system can often continue in degraded mode rather than complete downtime.
- Enables teams to work in parallel (each team owns one or multiple services).
- Allows scaling of services independently (e.g., spin up more instances of an Order service if that part is bottlenecked, without scaling the entire app).
Diagram – Monolith vs Microservices:
Monolithic Architecture: Microservice Architecture:
[ Web App (all features) ] [Auth Service] [Order Service] [Catalog Service]
| | | |
One deployment unit own DB own DB own DB
In the microservices side, each service is separate (perhaps running in its own process or container). They might interact through APIs:
Client -> API Gateway -> [ Order Service ] -> (calls) [ Payment Service ]
\-> [ Catalog Service ]
\-> [ User/Auth Service ]
Often an API Gateway or load balancer is used to route requests from clients to the appropriate services and to handle concerns like authentication, rate limiting, etc.
Benefits:
- Scalability: Scale services independently as needed.
- Deployability: Deploy updates for one service without redeploying the whole system. This enables continuous delivery for different parts of the system.
- Fault isolation: A bug or high load in one service ideally only affects that service (though in practice, cascading failures can happen if not designed carefully).
- Technological freedom: Can choose the best tool for each service’s job (polyglot tech stack).
- Team autonomy: Small teams can own services end-to-end.
Challenges:
- Complexity in distributed system: Network latency, handling partial failures, and debugging across many services is non-trivial.
- DevOps overhead: Many moving parts to manage (containers, orchestrators like Kubernetes, monitoring for many services).
- Data consistency: With separate databases, maintaining consistency (especially in transactions spanning services) is complex; patterns like Saga (for distributed transactions) are used.
- Testing is harder (need integration testing of interactions).
- Inter-service communication can add overhead (both in performance and in complexity of API contracts).
Microservices have become popular for large systems (Netflix, Amazon, etc. famously use them) because they enable scalability and agile development. However, for small to medium applications, a well-structured monolith can be simpler and perfectly adequate. It’s important to weigh the trade-offs.