A developing a server-side enterprise application. You must think of different clients:
- Mobile devices and its browsers.
- Native mobile applications.
- Desktop devices and its browsers.
- Exposing your APIs to 3rd parties.
- Integrating with other applications.
- Executing business logic, accessing a database or exchanging messages with different systems.
- Returning a response.
- Figuring out technology stacks.
- Keeping things in your mind such as CAP theorem.
- many more depends on the complexity!
It is very hard to define an architecture that supports as a set of loosely coupled, collaborating services using the Monolithic approach. Let’s imagine that you are building an e-commerce application that takes orders from customers, verifies inventory, and ships them. The application consists of several components including the StoreFrontUI, which implements the user interface, along with some backend services for checking credit, maintaining inventory and shipping orders. The application consists of a set of services.
Marching Towards Monolithic World
Unfortunately, this simple approach will have a huge limitation over time:
- Welcome to Monolithic Hell:
- Once your application has become a large, complex monolith, your development organization is probably in a world of pain.
- It’s simply too large for any single developer to fully understand. As a result, fixing bugs and implementing new features correctly becomes difficult and time-consuming for anyone.
- How about being an Agile at this point? The agile development will be impossible to achieve at this point.
- Hard to scale horizontally:
- Let’s say one module might implement CPU‑intensive image processing logic and would ideally be deployed in CPU-optimized instances.
- Another module might be an in‑memory database and would ideally be deployed in memory-optimized instances.
- However, because these modules are deployed together you have to compromise on the choice of hardware.
- How about reliability?:
- Every module is running in a single instance so a bug in any module, such as a memory leak, can potentially bring down the entire application down or cause a lot of latency!
- Imagine one part of the application consumes most of CPU or memory. Will horizontal scaling solve the problem? Or will the problem be postponed it?
- How about continuous deployment?:
- Let’s make small changes in somewhere in the application. The entire application needs to be deployed since every module is running together!
- How would you test that small change? You may be ended up testing the entire application if the impact of the change is not well understood!
- How long will it take to deploy that change to production? Since we are deploying all modules, it will take more time! If the application grows larger, this time goes with it everytime we make any changes.
- Being innovative:
- It is very complex to adopt new frameworks in the Monolithic Hell.
- Management of Monolithic Hell:
- Fixing bugs will be a pain as the codebase is difficult to understand.
- Implementing new changes will be a pain too without breaking different things and testing them.
- How about the new hire life? Understanding and learning will take more time for a new hire.
There are benefits too in this world 🙂
- You don’t have to deal with the additional complexity of creating a distributed system.
- Less deployment complexity.
- Decreased memory consumption (think the Microservice approach).
Let’s drive into Microservice architecture!
Marching Towards to Microservice architecture
The idea is to split your applications into sets of small interconnected services. So each functional area of the application is now implemented by its own microservice. This makes it easier to deploy distinct experiences for specific users, devices, or specialized use cases. However, there is a deployment complexity.
Typical Microservice uses RESTful Web Services. So each backend service exposes a REST API and most services consume APIs provided by other services.
Here are the key benefits:
- Strong Module Boundaries.
- Each microservice is relatively small.
- Easy to maintain and develop features.
- Enables the continuous delivery and deployment of large, complex applications.
- Independent deployment.
- Scale-out independently.
- Technology diversity and adopt new frameworks.
- Improved fault isolation.
Let’s talk about the cons:
- Welcome to the distributed system world!
- The distributed systems have their own problems. For example, think the remote calls which are slow and always at risk of failure (CAP).
- Developers must implement the inter-service communication mechanism.
- Partitioned database architecture.
- Welcome to Eventual Consistency!
- Maintaining strong consistency is extremely difficult for the distributed systems, which means everyone has to manage eventual consistency.
- Operating complexity!
- Manage a lot of services, which are being redeployed regularly.
- Testing the Microservice is more complex.
- Implementing changes that span multiple services.
- requires careful coordination between the teams.
- without using distributed transactions is difficult.
- Increased memory consumption since the microservice architecture replaces N monolithic application instances with NxM services instances.
Microservice vs SOA
SOA is the superset of Microservice as the Microservice has lightweight communication protocols.