Before talking about microservices we have to understand Monolith architecture and its challenges.
Monolith Architecture & it's challenges
Before microservices, the standard way of developing applications was monolithic architecture.
It means all the components of an application, the whole code is part of a single unit.
For example, if we had an online shop application all its components like user authentication, shopping cart, notification, payment, sales complaints, product catalogue and so on. All the code of these functionalities would be in one codebase.
Everything is developed, deployed and scaled as 1 unit.
The application must be written in 1 tech stack with a single run time.
Teams need to be careful to not affect each other's work if there are different teams for different components.
To update and make changes in even one component, we have to redeploy the entire application again and again.
Challenges with Monolithic Architecture
Applications become too large and complex.
Components/parts of applications are more tangled into each other.
You can only scale the entire app, instead of a specific component which results in :
The higher infrastructure cost.
and less flexibility in scaling the application up and down.
There is a difficulty if different components need different versions of dependencies.
The release process takes longer.
On every change, the entire application needs to be tested.
The entire application needs to be built and deployed.
Any bug in any module can potentially bring down the entire application.
The answer to all these challenges was microservices architecture.
What are Microservices?
In Microservices, we break down an application into essentially smaller and independent applications/services.
The best practice is to break down applications into components or services based on their business functionalities and not technical functionalities.
For example, microservices of an online shop application will be products, user, shopping cart, checkout, etc
In terms of size, Each microservice should do only 1 isolated thing/job i.e. 1 microservice for 1 job.
Each service should be self-contained and independent.
Apps should be loosely coupled which means that each service must be able to be developed, deployed and scaled separately without having any tight dependencies on any other services.
Each microservice has its own version.
How do microservices communicate with each other?
1. Communication via API calls
Each service has an endpoint where it accepts requests from other services.
Services can talk to each other by sending HTTP requests on these endpoints.
This is a Synchronous communication where one service sends requests to the other service and waits for the response.
2. Communication via Message Broker
It is Asynchronous communication.
Here services will send a message to the intermediary message service or broker and then the broker will forward that message to the respective service.
Common Distribution patterns: Publish/subscribe and point-to-point messaging.
3. Communication using Service Mesh
With service mesh, you have a type of helper service which takes over the complete communication logic.
So you don't have to call this logic in microservices and have this communication logic delegated to this external service
Advantages of using microservices
You can develop each service with a different programming language.
Each microservice team can choose their own tech stack.
Each team can develop the service independently without affecting others.
Disadvantages or Challenges with Microservices
Breaking down applications into smaller pieces added a lot of complexities.
One of the main complexity is configuring the communication between services
It is more difficult to monitor with multiple instances of a service distributed over servers.
How do we manage code for microservices applications in a Git repository?
There are two ways to manage the code for microservices applications in a git repository:
Monorepo
Polyrepo
1.Monorepo
Monorepo means using 1 git repository which contains all the services and projects.
A common way of doing this is using 1 codebase with folders.
There will be a folder for each service/project.
It makes code management and development easier.
You can clone and work only with 1 repo.
Change can be tracked, tested and released together.
Challenges or downsides with Monorepo
Tight coupling of services/projects.
It will be easier to break the criteria of loosely coupled services and make mistake of developing more tightly coupled code which is opposite to the microservices architecture.
When the application becomes really big means big source code which will result in slow git interactions. Cloning, pushing, fetching, etc will become slow.
In the case of the CI/CD pipeline, additional logic is necessary to make sure only the service is built and deployed which had code changes.
As there is only 1 main branch, all the projects and teams get affected if there is some issue.
2.Polyrepo
It is more preferred one.
Polyrepo means using 1 separate repository for each service/project.
Code is completely isolated.
You can clone and work on each service separately.
In the case of the CI/CD pipeline, each repository has its own pipeline.
Challenges or downsides of Polyrepo
Working on the project as a whole is more difficult.
Changes spread across different services must be submitted as separate merge/pull requests instead of having a single, atomic PR.
Switching between services becomes more tedious.
Searching, testing and debugging across multiple services from the code editor will be more difficult.
Sharing resources like Kubernetes, HELM manifests, etc difficult.
I hope you find it informative and helpful. If you like it please follow, like and share. I will keep writing informative blogs related to DevOps. Please give your feedback in the comments and check out my other articles as well. Thank You !!!!
You can reach out to me on Twitter and LinkedIn from my bio or mail me at iimransaifi1509@gmail.com
.