Monolith to Microservices : Ep1 : Are you ready ?
By: Priyal Walpita
Tags: Monolithic, Distributed Systems, Migration, Microservice Architecture

Overview

Microservices are the services that have been modeled around a business domain that are independently deployable. Nowadays, Microservices architecture is becoming a hype, since most of the tech organizations tend to port or migrate their existing architectures into Microservices. This article is all about moving from Monolith to Microservices architecture. The key objective of this article is to educate the reader on the aspects and considerations that should be taken into account when moving from Monolith to Microservices architecture.

To begin with our article with let us first understand what is ‘Monolith’.

What is a Monolith?

‘Monolith’ is a one unit of Deployment. When all artifacts/binaries in a system had been deployed together, we consider it as a Monolith. Monolith architecture is usually portioned in two ways. Which are as the Technically Partitioned and Domain Partitioned.

So, the Technical Partitioned Monolith is what we usually called the ‘Layered Architecture’, which consists of layers such as Presentation Layer, Business Layer, Persistence Layer, and Data Access Layer as shown in figure 1. Here, each layer consists of a clear responsibility that contributes to its functionality. There is a strict rule that we need to follow here as “one particular layer should communicate only with adjacent layers (up and down)”. If you violate this protocol it is identified as the “sinkhole” anti-pattern.

Figure 1: Technically Partitioned Monolith

On the other hand, in the Domain Partitioned Monolith, as shown in figure 2, there are no layers as mentioned above, but instead of that, we have a set of modules. These modules are usually wrapped around business functionalities that are subjective to the domain. One advantage in domain partitioned monolith is, if you want to do some changes which are related to DB schema, you need to update only that particular module and the database. In a layered architecture, you would be updating all layers to accommodate one DB schema change because the data is flowing through all layers. Shared components are one disadvantage in domain partitioned monolith there it leads to high coupling between domain or modules.

Figure 2: Domain Partitioned Monolith

Next, we will move on to understand the three types of Monolithic systems, which are as; Single Process System, Distributed Monolith, and Third-Party Black Box Systems. So let’s briefly understand what these systems are and how they work in the Monolithic architecture.

Single Process Monolith

These are the most common type when discussing monolith, where all of the code is deployed as a single procedure. These single process systems, shown in figure 3, always end up reading data from or storing data in a database, as simple distributed systems since they could be processed in their own right. Additionally, a vast majority of the monolithic systems that people tend to struggle with are likely to represent these single-process monoliths.

Figure 3: Single Process Monolith- All code is packed in a single process

Distributed Monolith

A distributed monolith comprises multiple services. However, in the deploying process, this whole system has to be deployed together ( one of the main reasons behind this is shared databases). The definition of a ‘service-oriented architecture’ may be well met by a distributed monolith. Also in an environment where not enough focus has been placed on concepts such as hidden information and business functionality cohesion, distributed monoliths typically do try to emerge.

Third-Party Black Box Systems

As part of the migration effort, we can also consider some third-party software as monoliths that we may want to “decompose”. These could include things such as payroll, CRM, and HR systems. In this case, a common fact is that, since its software is already developed by other individuals, you don’t get the ability to change the code.

Is Monolith Bad?

Using Monolith is not bad at all. This technology was practiced for years and years. Pursuing this further, let us now move on to understand the usages and challenges which could encounter when using Monolith.

Usages

It is a much simpler deployment topology that could avoid many of the pitfalls associated with distributed systems.

It can lead to much simpler workflows for developers; can also greatly simplify monitoring, troubleshooting, and activities such as end-to-end testing.

Within the monolith itself, monoliths can also simplify code reuse.

With the user choices, it is much easier to work with monoliths.

If you are a startup, it is better to use Monolith in most of the cases than moving on to Microservices

If you need just crud operations monolith could be used when obtaining solutions.

When you have a limited functional application with a definite number of users (ex: On-premise application)

When your requirement is just a PoC or a Pre-Sale

When you are not sure about the future of the application

Challenges of Monolith

The monolith, whether it is a single-process monolith or a distributed monolith, is frequently more susceptible to the dangers of high coupling and low cohesion. This happens when they could get in each other’s way as you have more and more individuals working in the same place. Confusion may occur over who owns what, and who makes choices. These difficulties of confused lines of ownership are usually referred to as a ‘dispute of delivery’.

Let’s now understand when you could use Microservice for your existing architecture. Recently, people have come to the view that monolith as something to be avoided, as something inherently problematic. On the other, hand keeping monolith architecture is a choice. Initially, they communicate via networks with each other, and as an option for architecture, they deliver many options to address the problems you may face and follows micro service ideas that are based on multiple microservices that work collaboratively.

But, if you are planning a migration, initially we need to explore several less technical issues as mentioned. You could start this by, understanding things like, ‘where should you start the migration’, ‘how should you manage the change’, ‘how do you bring others along on the journey’, and things like ‘should you even use microservices in the first place’. One thing that you have to keep in mind is that having Microservice does not make you win. It should be a conscious decision, based on rational decision making. This is done when you can’t actually do with your existing system infrastructure so that you migrate to a microservice architecture.

What is a Microservice?

It is crucial that we have a general, shared understanding of what microservice architectures, shown in figure 4 before we dive into how to work with microservices. As in the definition of Microservices, mentioned at the beginning of the article, Independent deployability is the principle where, without needing to use any other resources, we can make a change to a Microservice and deploy it in to production . It is most important how you treat your systems of deployments and sometimes it could be identified as a discipline you practice as well.

Figure 4 : Microservices

They communicate with each other through networks, and as an architecture choice, they offer several options to fix the issue you face with. The architecture of microservices is created on a number of collaborating microservices as well. Microservice can be considered as a distributed service-oriented architecture (DSOA) and moreover it has the advantage of being uncertain towards technology.

In order to ensure independent deployability, it is important that we assure that our services are loosely connected( ie: low coupling and high cohesion). Simply we could say that, without modifying anything else, we need to be able to change one service. We could say that this implies that between providers we need explicit, well-defined, and stable contracts.

Why do you want to move to Microservices?

Before answering this question you could ask yourself these three questions.

What are you hoping to achieve?

Have you considered alternatives to using Microservices?

How will you know if the transition is working?

But you need to remember that prior to moving on to Micro Services, checking should be done on the following requirements in your current architecture.

Is your product or service SaaS based?

Do you want to scale your system with increasing number of users?

Do you need Elasticity?

Do you need to roll out bug fixes quickly?

Do you need high Resilience and Robustness?

Do you need to scale your development?

Do you have performance issues where you cannot solve in current architecture?

Microservices connect via networks, and they provide several options to solve the problems you face with. And furthermore, it would lead to having additional headaches as well which you didn’t encounter in the Monolithic architecture. If you are moving to any distributed architecture pattern, you should not fall into the falsies of distributed systems. It could be seen that a Microservice design is based on multiple independent services. This implies that we need simple, well-defined, and secure arrangements between providers. Furthermore, it is not feasible to overstate the significance of taking an incremental approach to extracting microservices. Since errors are always possible, so if accepting that as a given, you should aim to make slight mistakes rather than going larger mistakes. Since most of us work with real-world customers, we can’t afford on spending months or years on a big bang rewrite of our application. As Martin Flower once said, “If you do a big bang rewrite, the only thing you are certain of is a big bang!”

.So that the aim should be to create a microservice where it has minimal impact on your architecture and getting them deployed as a part of the production solution where you could start learning from the experience along having benefits.

Initiating Microservices architecture is not easy though, it is costly and complex as well. We used to call them an extra tax-related to Microservices.

Microservices Tax

The following are some of the factors you need to consider if you are moving to Microservice architecture.

Observability

Service Discovery

Service Orchestration

Fault Tolerance

Circuit Breakers

Build and Deployment Automation

Testing Automation

Polyglot technical stacks

Technically capable teams

If you are planning to initiate a Microservices project or migrate into Microservices without the aforementioned initiatives, most probably you would end up in a disaster. As an example, it is unhuman to monitor and track 150 odd production services without service discovery and service orchestrations such as Eureka, Consul, and Kubernetes or Docker swarm for orchestration. Without a distributed tracing framework such as Jaeger, it is almost impossible to track down and pinpoint any error in the production environment. How can you identify manually which service is down and then there should be a fallback mechanism without using a circuit breaker such as Hystrix? Can your QA team perform manual testing of more than 100 services on each release? Can your DevOps team deploy more than 50 services into production manually with minimal downtime without using continuous delivery and integration pipelines?

So as a mantra, you should get prepared with this homework before you jump into the distributed architecture. Otherwise, most probably you would end up with a disastrous big ball of mud!

So when to start the Migration?

Apart from the technical feasibilities that I mentioned earlier, you should get support with the following items as well within your organization.

Find a good support (mentor/ C-level support/ consultant)

Developing a Vision and Strategy

Define short term goals

Communicating the change vision

Change organization culture (Try to get rid of dedicated teams for tech stacks. E.g.BA, Dev, QA, Support, IT, Infra, Deployment etc.)

Anchoring the new approach and culture

Identify the components for decomposition using one of the collowing techniques

Domain-Driven Design (DDD)

Event Storming

Actor Action

Figure 5: Identifying the components for decomposition Ref :Monolith to Microservices by Sam Newman

If you can accurately fill the above matrix with your existing monolith’s modules, then you have a starting point. If you have a well-designed monolith with less coupling/connascence and high cohesion, then this task would be much easier. So, then you can start your migration from the top right-hand corner.