Monoliths To Microservices
Monoliths To Microservices
Monoliths To Microservices
Before we start discussing about how we are going to migrate let's first discuss briefly about monolith and
microservice architecture.
Monoliths are large code bases which contain all the logic required for you to run your application. All the
relevant code is kept in a single repository.
Whereas in a Microservice architecture our application is made of small services communicating with
each other using protocols like HTTP or GRPC.
2. Less chances of breaking change Let's take a scenario. We have two modules Profile and Auth.
Initially the profile ID was integer but we changed it to string. So the Profile module has function
getProfile(string ProfileID) but the auth service has a function call getProfile(id) where id is int.
In Monolith architecture Auth module communicates Profile module via function call. The parameters
that we are passing is clear. So if the parameters are invalid then we can catch them at compile time.
However in microservice architecture Auth module has no idea that the function parameters have
changed. So all communication with profile service will break.
Since the code and expectation in monoliths are at one place it is much harder to have breaking
changes.
But why should we migrate from Monolith to Microservice architecture ?
1. Separation of concerns In a microservice architecture we can make changes to one service without
affecting other services. However in monoliths since all our code is at one place making changes will
affect the entire system.
2. Engineering is easier Working with microservice architecture can be easier since the developer
needs to understand only a particular microservice providing the functionality he/she will be working
on and not the whole system.
For e.g., an engineer working with the auth service is not concerned with the functionalities of profile
service.
4. Better scalability
Each service can be scaled independently. So it is more cost effective and saves time compared to
monoliths.
5. Great for large teams Microservice is a great choice when we have a large team. Each team can
work on a service which makes the development process much efficient.
6. More flexibility Each service can be written in different language and tech stack. This allows teams to
pick up a tech stack that is the most appropriate.
The problem with this approach is the huge engineering challenge. We need to write all microservices,
make sure databases are correctly configured and then redirect user. So we need to invest a lot of
resource in the very beginning.
Whenever we want to add a new module to our application, instead of adding it to the monolith we can
make it a single service. This approach is better because we need less investment in the beginning and
the migration will be much smoother.
Okay, now we have added a new service but,
We can also go for a better approach. Instead of making the service go through the contract before
every call we can implement a library for each service. Developers can use the function defined in
the library to make network calls. This library is called the client library.
Router We also need to route requests from one service to another. We can use something like a
service registry here. It maps the the methods to handlers. So whenever we get a request having a
particular method we know to which service we need to send the request.
Simplifying deployment As we increase the number of services in our system the deployment
process should not become complex. To simplify the deployment process we can have automated
deployments (e.g., If we push code to main then it is tested and deployed automatically). We can use
CI and CD pipelines, containers and service dashboards to automate our integration, development
and deployment.
Communication between services Let's try to understand this point with few examples. For some
services we might need quick response, for that we can use request-response architecture. For other
services whether the message reaches the other end or not is not that critical. In such cases we might
use a message queue. For sending bulk data to any service we can use batch processing.
As you can see, we choose communication process for each pair of services as per our need.
Logging
A request can be routed from service A to service B and so on. If there is a separate logger in each
service then in case of any error or failure it will be a nightmare to find the bug. So we need a logging
service that logs events in every service in our system to a separate database.
We can use something like Apache Kafka and Lucene.
But we want to separate a smaller service, one that handles credit card transactions with third party
services like Razorpay, stripe etc. So it looks something like this:
Now let's ask ourselves the 3 questions:
Is the credit card service used by any other service except payment? No
When there is a change in payment service requirement will there be change in credit card
requirement? Yes. So is there sufficient decoupling? No
Are the business requirement of payment and credit card service different? No
Initial Infrastructure cost Microservices are expensive. Cost of logging, building a deployment
infrastructure etc is not worth it for a small team. So now the question arises when should we move to
microservice architecture?
We can get a rough idea form the table below: | Startup | Medium scale companies |Large organization| |---
|---|---| |1 developer can work on at most 2 microservices*|1 developer can work on at most 1
microservices*|2-4 developers can work on at most 1 microservices |
You can check out more designs on our video course at InterviewReady.