Microservices
Tags: programming, devops, tutorial, kubernetes
Published: 2022-11-20 11:53:41

Usually, when we make applications (especially as beginners), we tend to make one application to do everything. This application is said to follow a monolith architecture.

## What is a Monolith architecture?
- The standard way of writing code here all the components are a part of a single unit/ codebase.
- The app must be written with one tech stack. 
- Teams need to be careful to not affect each other's work.
- Every time you update a part of the application, you need to redeploy the entire application.

## Challenges with the monolith architecture
- Applications become too large and complex.
- Parts are more tangled into each other.
- You can't scale particular components which leads to higher infrastructure costs. 
- Difficulties arise if different services require different dependency versions.
- Longer release process.
- For every change made, the entire application needs to be tested. 
- A single bug in a relatively insignificant component can bring down the entire application.

Since there are a lot of problems with the standard monolith structure, we resolve them by using **microservices**.

## What are microservices?
- We break down the application into several small/micro applications.
- What does their architecture look like?
	- The splits are based on each component's business functionalities. 
	- It follows the idea of 'Separation of concerns'- 1 service for 1 specific job.
	- They must be self-contained and independent of each other. Each service must be developed, deployed and scaled separately even though they are a part of the same application. (Known as **loose coupling**)

## Communications between microservices
- Usually done using API Calls.
	- Each service has its own API and they can talk to each other by sending HTTP requests
	- It is a synchronous communication
- It can also be done asynchronously using a message broker
	- Common patterns- Pub/Sub and point-to-point messaging
- A third way to communicate is by using a service mesh.
	- There's a helper service that takes over the complete communication logic.
	- You don't have to code the communication logic into the microservice, it is delegated to the service mesh.

## Downsides to using microservices
- Added complexity because the microservices application is a distributed system.
	- Configuring the communications between services for scenarios where one of the services is down.
	- More difficult to monitor with multiple instances of each service distributed across servers. 
Tools for overcoming these challenges have been built over the years. One of them is *Kubernetes*. 

## CI/CD pipelines for microservices
- Companies like Meta, Google and Netflix deploy hundreds of microservices every day. The complexity of the pipeline increases with the number of such services deployed.

## Monorepo vs Polyrepo
- Monorepo means using 1 git repository that contains many projects. 
	- Each service has its own folder/ directory.
	- Makes code management and development easier.
	- Clone and work only with 1 repo.
	- Changes can be tracked together, tested together and released together. 
	- Share code and configurations like docker-compose and manifest
- Some of the challenges are:
	- Tight coupling of projects. 
	- Easier to break the 'loosely coupled' criterion.
	- Cloning, fetching and pushing slowdown due to increased size. 
	- Makes pipeline code more complex and challenging to write.
	- If the main branch is broken, the entire repo is gone.
- Used by companies like Google.
- Polyrepo means that each service has its repository.
	- Code is completely isolated
	- Clone and work on them separately.
	- In services like GitLab, you can have projects to configure connected projects (**Groups**).
		- This helps to keep an overview.
		- Create shared secrets, CI/CD variables, runners, etc.
	- The CI/CD is more straightforward. 
- Some downsides are:
	- Cross-cutting changes is more difficult.
	- Changes spread across projects must be submitted as separate Merge requests instead of a single, atomic MR.
	- Switching between projects is tedious
	- Searching, testing and debugging is more difficult.
	- Sharing resources is relatively more difficult.


I made these notes after watching Techworld with Nana’s [video](https://youtu.be/rv4LlmLmVWk). Let me know what you think of it and if you’ve loved it, drop a like :)