Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Monolith Architecture and Microservice Architecture are in common practice in the software industry today with the latter adopted and revered widely. This article will discuss the criteria to use the specifics of this architecture, and the pros and cons of each of these with relatable examples. The article also discusses the Bulkhead pattern and CQRS pattern.  

Analysis for the requirements and structure of an application always precedes building the application itself. Identifying the needs through an arduous design phase, and acknowledging the resources available to the team, appropriate architecture is chosen that is suitable for the project. According to industry standard practices today, systems are mainly designed with two approaches:  

  • Monolithic Architecture 
  • Microservices Architecture 

The discovery process for the type of architecture to be used for the application system involves numerous points to take into consideration.  

  • Stakeholders 
  • Functionalities 
  • End users 
  • Input and output process 
  • Engineering teams 

Thereafter, analyzing the resources in availability, the next steps can be looked after. A great starting point to check-in for the resources would be,  

  • Engineering resources 
  • Financial resources 
  • Timeframes 
  • Internal knowledge 

Monolith

Monolith can be described as a mono-managed system where the application is designed for all application tiers to be managed in a single unit.  

Monolith Architecture  

Monolith Architecture is a traditional approach to design software. It is a single-tiered software program designed in a manner where data access and user interface are all combined in one specific program on a single platform.

In a monolithic architecture, all the application tiers lie in the same unit and are managed in a singular repository sharing system resources such as processor and memory. The programming language used for the entire application is also relied to only one and the product is released is released using a single binary.  

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Let us suppose, a team develops a food ordering system using monolithic architecture. With this approach, the User Interface could be a mobile application interface or a website. The business logic would consist the code which provides the functionalities for the ordering system such as inventory, or order management, business payment, and so on. This main system would be written in one particular language such as C# or Java and would be stored in one repository. The customer data and all other data would be the part of Data Interface with DB. These components would be managed as a single unit and thus the release would be done using a single binary.   

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Benefits

  • Simple Development, Deployment, and Testing 
  • Fewer Cross-Cutting Concerns 
  • Less Operational Overhead 
  • Performance  

Trade-Offs

  • Deploy all or none 
  • Scale all or none 
  • Single point of failure 

Microservice Architecture

The application tiers are managed independently in the microservice architecture, each as separate units such that the units are in the different repositories each having its allocated resources for processor and memory. The APIs are well-defined to connect the units to each other and the entire application might use one or more programming languages and are released using each individual binary.  

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Let us consider, the same food ordering system we designed earlier using a monolithic approach now this time with microservices architecture. The mobile application or website will still be the interface user can order food. But, in this case, the food ordering system – the main business logic will be split in numerous small, independent units for instance – login and authentication, business payment - billing, payment confirmation, delivery location and so on. Each of these units can be developed using multiple different languages and be interacted with each other through APIs. From complex functionalities to artificial intelligence for recommendation systems to appear on the application to offer new dishes to users, a lot can be integrated. All of these are possible with each different team handling different parts of the application. Each unit of the codes is stored in separate repositories.

The data layer would contain the functions which stores and retrieve data of the order, payment gateways integration, securities pieces for authentication and other details of customers including delivery location. All of these units are released using their own individual binary. 

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

To learn more about Microservices, check this video,

Identifying a Bounded Context

The primary objective while finding model boundaries and size for each individual microservice is not about the getting most granular possible separation but rather to get the most meaningful separation for smaller microservices which are guided by the domain knowledge and expertise available. The emphasis should always be on business capabilities rather than size. Wherever cohesion is acquired for a specific part of the application based upon the number of dependencies, those segments need a single microservice. One of the clearest ways to realize where and how to group together or break apart microservices is by looking upon the cohesion needs. Finally, as more knowledge of the different domains is obtained, the size of the microservices too can be adapted to in an iterative process. Also referring to Conway’s Law, application tends to reflect the social boundaries of the very organization that produces the application. And now, if we can reverse this approach, we can build the boundaries as our desire our company and teams to be organized which allows us to bound teams as per the microservices we choose to develop as a separate entity and get together the people of specific expertise for that microservice. 

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Advantages of Microservice

  • Scalability 
  • Easier Deployments 
  • Problem Isolation 
  • Single Responsibility 
  • Deep domain knowledge 
  • Polyglot Programming 

Disadvantages of Microservice

  • Cultural Change 
  • More Expensive 
  • Complexity 
  • Less Productivity 
  • Communication between services 
  • Harder to do integration tests 
  • Well thought architecture right from the beginning 

Migration Tips from Monolith to Microservice Architecture

Do not switch from monolith to microservice all at once. This is not just a tedious process but could succumb to errors and failures. Instead, take a divide and conquer strategy. Inspect the monolithic system to realize where the biggest problem arises and start to transform that part first into Microservice.  

2 Second Rule

2 Second Rule is a loose principle in software engineering for usability first approach where it is believed a user shouldn’t have to wait for more than 2 seconds for any kind of response from the system. From application launch time to website load time, an individual task should always be completed within that 2 second time frame. This holds a significant value from the perspective of user experience. With this in concern, critical APIs are mostly written in Go or Scala. Howsoever, efficiency also needs to be balanced with robustness.

Pattern: Bulkhead 

Bulkhead pattern is an architecture for application design that is highly tolerant to failures. The elements are isolated into pools such that the failure of one pool will not affect the functioning of the others. This pattern is derived from the sectioned partitions (bulkheads) in ship’s hull which is designed and compartmentalized in a way that if one section gets damaged and gets filled by water, the sectioned partition approach saves the ship and prevents from sinking.  

Here, workload 1 faces some difficulties and comes to halt such that Service A is stopped from functioning. But due to the Bulkhead pattern approach, Workload 2 will be catered two using different pools thus Service B and C functioning properly with the workflow being intact.  

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Prevents from

  • Propagation of Failure  
  • Noisy Neighbors 
  • Unusual Demand 

Pattern: CQRS 

The CQRS stands for Command Query Responsibility Segregation. This pattern separates the operations of reading and updates for data storing. Maximization of Performance, Security, and Scalability are the benefits of implementing the CQRS pattern. Migrating the system to the CQRS approach helps the system to evolve better in time preventing merger conflicts at the domain level due to update commands. Unlike traditional approach which would be well enough for simple CRUD operations, the complex applications would face issues with the traditional architectures. But with CQRS, making commands task-based rather than data-centric, asynchronous processing and separating the read and write into different models, this isolation provides a better approach to update and query data. 

Monolith, Microservices Architectures And Bulkhead, CQRS Patterns

Thus, in this article, we talked about Monolith Architecture and Microservices. We learned about its benefits and trade-offs with a proper example to understand it in a deeper sense. We also understood about finding a bounded context and the migration tips for shifting systems from monolith to microservices architecture. We also discussed 2 Second Rule, Bulkhead Pattern, and learned about CQRS Pattern.  

References

  • https://www.udacity.com/course/cloud-native-application-architecture-nanodegree--nd064 
  • https://docs.microsoft.com/en-us/azure/architecture/microservices/migrate-monolith