What is Microservice Architecture?
and how to properly do it with Self-contained Systems (SCS).
This week’s issue brings to you the following:
What is Microservice Architecture?
What are Self-contained Systems (SCS)?
Why is the CAP Theorem Important?
Bonus: Free e-book “Designing Distributed Systems”
So, let’s dive in.
Postman's VS Code Extension (Sponsored)
Postbot is now available across Postman with enhanced capabilities! The latest refresh of Postbot now offers a consistent, conversational interface available to you across your workspace. Learn how you can leverage Postbot throughout Postman to get contextual assistance.
What is Microservice Architecture?
Have you ever wondered why companies like Netflix and Amazon seem to roll out features at the speed of light? The secret might be hidden in their tech stack based on Microservice architecture.
At its core, Microservice architecture is about breaking down an application into a collection of small, loosely coupled services. Each service runs a unique process and communicates through a well-defined API. Each service is a separate codebase, which can be managed by a small development team and deployed independently.
Sam Newman defined Microservices in his book "Building Microservices" as:
Microservices are small, autonomous services that work together.
Microservices architecture is the best fit when we have applications with high scalability needs, many subdomains, and possibly multiple cross-functional development teams. Take into account that organizational shape influences your architecture.
Critical Elements of Microservice Architecture:
Load Balancer: Ensures even distribution of incoming network traffic across various servers.
CDN (Content Delivery Network): A distributed server system that delivers web content based on the user's location. It's about bringing content closer to the end-user, making page loads faster.
API Gateway: This is a single entry point for all clients, and it directs requests to the appropriate microservice using REST API or other protocols.
Management: Monitoring and coordinating the microservices, ensuring they run efficiently and communicate effectively.
Microservices: Each microservice handles a distinct functionality, allowing for focused development and easier troubleshooting. They can talk with each other using RPC (Remote Procedure Call). Services are responsible for persisting their own data or external state.
When building such architectures, we should strive for every service to have a single responsibility with clear boundaries. The services should communicate asynchronously, have a separate database, and build+deployment per microservice.
Benefits of Microservice Architecture
Scalability: Scale up specific parts of an app without affecting others.
Flexibility: Each microservice can be developed, deployed, and scaled independently.
Resilience: If one microservice fails, it doesn't affect the entire system.
Faster Deployments: Smaller codebases mean quicker feature rollouts.
Drawbacks of Microservice Architecture
Complexity: More services can lead to a more complex system.
Eventual Consistency: Maintaining consistency across services can be challenging.
Network Latency: Inter-service communication can introduce delays.
Error handling: When an error happens, it's hard to debug why and where it happened.
Wrong decomposition: If you do a bad decomposition of your monolith, you can develop a Distributed Monolith.
If you want to learn more about microservices, check out the book “Building Microservices” by Sam Newman:
And the free book for .NET Microservice Architectures by Cesar de la Torre, Bill Wagner, and Mike Rousos:
Also, to handle different trade-offs when creating microservice architecture, we need to know patterns such as Circuit Breaker, Saga, etc. Check Design patterns for Microservices and monolith decomposition strategies.
What are Self-contained Systems (SCS)?
Self-contained Systems (SCS) are a software architecture approach that prioritizes the decentralization of applications into independent systems, each with its domain logic, UI, and data storage. Unlike Microservices, smaller services focused solely on business logic, SCS are larger and encompass a broader scope within a specific domain.
SCS are systems that represent autonomous web applications. They include web UI, business logic, and database and might have a service API. A single team usually owns them.
The main advantages of such systems are:
Autonomy: Each SCS operates independently with its database, business logic, and user interface.
Domain-aligned: SCS is structured around specific business domains, ensuring each unit represents a coherent and meaningful set of functionalities.
Decentralized Data Management: Individual databases per SCS ensure data consistency within its boundary, reducing cross-service dependencies.
Technology Diversity: Allows for different technology stacks to be used across other SCS, suiting the specific needs of each domain.
Explicitly Published Interface: Well-defined interfaces for interactions with other systems, maintaining a clear contract while preserving encapsulation.
Independent Deployability: Each SCS can be deployed, scaled, and updated independently without affecting other systems.
Why Self-contained Systems (SCS) has the edge over microservices:
Broader scope: SCS has a broader scope encompassing the UI, business logic, and data storage within a bounded context
Reduced Operational Complexity: Microservices can lead to high operational complexity due to the management of many smaller, interdependent services, while SCS is more significant and more autonomous.
Data Consistency: SCS manages its data, which can lead to better data consistency within each system, while Microservices often rely on a shared data store.
Reduced Inter-service Communication: SCS, by encapsulating more functionality, requires less inter-service communication than microservices.
Better Fit for Certain Domain Complexities: In cases where domain complexities are high and domain boundaries are clear, SCS might provide a better architectural fit due to their domain-aligned nature.
Such systems go well along with Domain-Driven Design (DDD). The first step in creating such systems is domain analysis, which can be conducted by identifying bounded contexts that align with specific business domains. Each bounded context is then encapsulated within an SCS, which comprises its own data management, business logic, and user interface, ensuring each system is autonomous yet able to interact with others through well-defined APIs when necessary.
If you want to learn more about Self-contained Systems, check these resources:
Self-contained Systems by INNOQ.
“Self-Contained Systems (SCS): Microservices Done Right,” InfoQ article.
“Our journey from Microservices towards Self Contained Systems,” Swissquote article.
Self-contained service at Microservices.io.
CAP Theorem
The CAP theorem is a fundamental concept in distributed systems and databases. It stands for Consistency, Availability, and Partition Tolerance, which are three properties that a distributed system can have. Yet, the theorem states that a distributed system can't simultaneously provide all three of these guarantees:
Consistency: This means that all nodes in the system see the same data simultaneously. So, if a change is made to the data on one node, all other nodes will see that change immediately.
Availability: Every request to the system receives a response without guarantee that it contains the most recent write. The system continues to operate and provide responses even if part of the system is down or some nodes are not communicating.
Partition Tolerance: The system continues operating even if communication among the nodes is unreliable, meaning some messages are lost or delayed.
The CAP theorem is essential because it helps us understand the trade-offs in designing and using distributed systems. For example, if we design a system where every read receives the most recent write (Consistency) and the system continues to operate despite network failures (Partition Tolerance), we may have to compromise on availability.
Network partitions are standard in real-world applications, so systems must be partition-tolerant. This means we usually must choose between consistency and availability when designing microservice architectures. When network partitions are a reality, choosing availability might mean tolerating some data inconsistency, while opting for consistency could lead to reduced availability.
Different databases are designed with various CAP guarantees. For example, MongoDB is a CP (Consistent and Partition-Tolerant) database, while Cassandra is an AP (Available and Partition-Tolerant) database.
Yet, it's important to note that the CAP theorem is a simplification and doesn't cover all aspects of the design space. For instance, it doesn't consider latency, a critical factor in many real-world systems. Also, the choice of a database should be based on something other than the CAP theorem. Other factors should also be considered, such as the specific use case, the data's characteristics, and the application's requirements.
Free e-book: Designing Distributed Systems
Check out the free book by Brendan Burns, a creator of Kubernetes on Distributed Systems. In this book, you will learn about the following:
How patterns and reusable components enable the rapid development of reliable distributed systems.
Split your application into a group of containers on one machine using the sidecar, adapter, and ambassador patterns.
Explore loosely coupled multi-node distributed patterns for replication, scaling, and communication between the components.
Learn distributed systems patterns for large-scale batch data processing.
Download the book from here and the labs for the book.
More ways I can help you
1:1 Coaching: Book a working session with me. 1:1 coaching is available for personal and organizational/team growth topics. I help you become a high-performing leader 🚀.
Promote yourself to 19,000+ subscribers by sponsoring this newsletter.