When I started off my career , Microservices weren’t as wide spread as it is today. Even though products that started off later leaned towards microservices , the market was still full of legacy monolithic software products. Since then, I have noticed that most of the companies started moving away (even migrating their existing products) into microservices due to different factors from the point of view of different stakeholders. We will discuss them later. This post is meant to discuss about what monolithic projects are and how microservices came into picture. Hop on!
Monolithic Applications: The Giants
Imagine how people write their individual personal college projects when they start with their engineering journey. In my case , I remember coding my way to creating an online airline reservation system as my very first project to understand using a database.
Now extrapolate it with all the standard features a product in business has like authentication , logging, capturing metrics , having the core CRUD logic for running the system, rate limiting, security policies, a database , UI for the presentation logic etc. It becomes huge. All of this comes under a single repository and project. This is essentially the base nature of a monolithic application. Its like everything we want unified into one single resource.
We can thus define a monolithic application as having the following characteristics :
Single codebase.
This means that every functionality is part of one single codebase. Thus every developer working on a monolithic application are essentially working on the copy of the same project. This makes code management tough.
Tight coupling.
There is less separation of responsibilities here. Everything will be tightly coupled and difficult to debug.An issue in one component can snowball into a bigger issue breaking multiple functionalities of the application.
Centralized Deployment
The codebase , since it is huge and singular , will be built into a final deployable artifact (eg: We had these old Java EE monolithic applications built into WARs and EARs ) and deployed into a powerful server.
Vertical scaling
To handle more requests and load, for monolithic applications the resource limits for the server machine monolithic application is deployed on is increased. (eg: RAM , HardDisk, Processor etc)
MicroServices : The mighty army
Imagine you had help on your college project. That you didnt have to do everything yourself. Somebody took care of authentication, you took care of the CRUD logic, somebody did the logic for capturing metrics, someone else did the UI etc. Consider being able to stitch all this together with some communication mechanism , so that they can act coherently. This way , the trouble for integrating everything into one is avoided and velocity development is also high, since everyone has their own task and responsibility. They can develop without waiting for anybody. This certainly improves the pace of development. This is essentially the base nature of microservices approach.
Here the units developed by each of your friend correspond to a microservice, and the way they communicate with each other represents the type of web communication like REST, gRPC etc. Its like a well organised army , where everyone has an assigned responsiiblity to achieve a common goal. (from the perpective of a developer and also from the perspective of a software component). MicroServices have the following characteristics:
Multiple code repos
The final product is made up of multiple smaller projects each having their own function/responsibility. For example, a JS project for showing the Reservation System UI, a spring Java project for the CRUD operations, a spring Java Project for authentication and user management, a small golang based rate limiter proxy service etc
Scalability
Microservices are usually synonymous with using cloud and are deployed into different containers in a machine. According to need , we increase the no of containers to serve the requests and load. This is called horizontal scaling. Since each project is having its own container, we can individually have different no of containers for each project based on the load it has on container.
Availability
Since they can be deployed into multiple containers in multiple data centers, it helps make sure that the system is always available . Even if one container goes down, we can make sure there will be other containers to pick up the work/ serve the requests.
Continuous Delivery
Microservices enable faster development and deployment cycles due to their smaller, independent units. This also reduces the dependencies teams or developers of different projects have on each other.
Team Autonomy
Independent teams can own and develop individual microservices, fostering innovation and ownership
Modularity
Microservices make it easier to add new features or remove old ones without affecting the entire application.
Which one to use ? Monlithics or MicroServices ?
The choice between monolithic and microservices architectures depends on various factors, including project size, team structure, and specific requirements. Here's a breakdown of their key advantages and disadvantages to help you make an informed decision:
When to Choose Monolithic Architecture:
Small projects: For smaller applications, monolithic architecture might be sufficient.
Tightly coupled systems: If components are highly interdependent, a monolithic approach can be easier to manage.
Rapid development: When time-to-market is critical, a monolithic architecture can accelerate development.
When to Choose Microservices Architecture:
Large, complex systems: For large-scale applications with many components and dependencies.
Independent teams: If you have multiple teams working on different parts of the application.
Scalability requirements: If you need to scale different parts of your application independently.
Technology flexibility: If you want to use different technologies for different components.
Update: As one of the readers pointed out, we cannot really reduce every architectural decision to just monoliths vs microservices. This is a very vague abstract differentiation which does not take into account the multitude of ways a developer manage and deploy code, the usage of external libraries, the communication through network etc