Microservices, Where Did It All Go Wrong • Ian Cooper • GOTO 2024
This YouTube presentation discusses the challenges and pitfalls of microservices architecture. Key points include:
The Problem with Microservices:
- Misunderstanding of “Micro”: The focus shifted from the replaceability of services (the original intent) to the number of lines of code, leading to the creation of excessively small and numerous (“nano”) services.
- Increased Complexity: Thousands of microservices result in a massive increase in integration points, potential failure points, latency, and operational overhead (monitoring, logging).
- Tight Coupling: Ironically, many microservice implementations exhibit high coupling despite the intention of loose coupling, leading to long release cycles and difficulty in making changes.
- Loss of Understandability: The sheer number of services makes it difficult for anyone to understand the system’s overall functioning.
- Conflation with Containers: The misconception that a microservice is simply anything running in a container (e.g., Lambda functions, Kubernetes pods) has fueled over-adoption.
- Organizational Issues: Using microservices to solve team availability problems (i.e., “whoever is free builds a new service”) often leads to poor design choices.
Finding the Right Balance:
- The Fundamental Theorem of Software Engineering (1975): The core principle of breaking down systems into smaller, independently solvable parts remains relevant. The key is finding the right size – not excessively small.
- The 4+1 Architectural View: This approach (logical, development, process, physical) offers a structured way to design and implement a microservices architecture, addressing each aspect separately.
- Domain Storytelling & Subdomain Modeling: Techniques to identify natural boundaries within the business domain, leading to more cohesive services. Focus on processes rather than entities.
- Macro Services: An alternative approach for situations where microservices are overly granular or complex inter-service communication is unavoidable. This involves larger, more cohesive services.
- Identifying Integrators & Disintegrators: Features (like ACID transactions) that force components together versus features that suggest separation.
- Bounded Contexts: These are collections of people, processes, and technology that deliver software, and ideally align with subdomains. However, they are separate concepts, and this alignment can drift over time.
- Refactoring and Resilience: The speaker highlights the importance of replaceable services to adapt to changing business needs, and suggests exploring Barry’s residuality theory for more resilient architectures.
Practical Advice:
- Start with a Logical Model: Understand the business domain and its subdomains before designing the software architecture.
- Iterative Approach: The first attempt at defining microservices is unlikely to be perfect; expect iteration and refinement.
- Consider Macro Services: If a domain is too complex to split easily into independently deployable units, a macro service might be a better choice.
- Avoid Nano Services: Strive for services that are appropriately sized, not excessively small.
- Choose Appropriate Communication: Prioritize asynchronous communication (messaging) over synchronous (RPC) where possible.
The presentation concludes that finding the optimal balance between monolithic and microservice architectures requires careful consideration of the business domain, team structure, and technical constraints. There is no one-size-fits-all solution.