The Path to Microservices: Opening Chapter
Microservices architecture is so popular in software development nowadays. Software engineers always use this architectural style to develop a system to support high traffic and scale the instances horizontally. Before diving into Microservices, let’s take a look at Monolithic architecture.
Monolith
In monolithic architecture, everything is coupled together. Look at the Backend component, inside this component, we might have different modules like user, payment, order, product, etc., but under a monolithic architecture design, all these modules are coupled in a single application. That said, a single application serves all functionalities and all traffic goes into a single application directly. What happens if your server cannot support that much traffic? Your application will go down.
You may say we can add one more server to split the traffic and use a load balancer to route the requests. Yes, you can. But, you might not able to utilize your system resources reasonably. Or you may say we can add more hardware resources to the server. Yes, you can. But, there is a physical limitation on a single machine. It cannot support that much hardware (Vertical Scaling).
What if the build time is extremely long and we want a fast deployment for a single feature only? We don’t want to deploy all the modules again when it is nothing changed. What can you do to solve this?
To solve these kinds of problems, Microservices architecture comes.
Microservices?
Okay, now people adopt microservices architecture to solve the problems that monolithic architecture might not support well. A single backend is split into different microservices now. As you can see in the diagram above, we split a system into different domains. For example, user service, product service, order service, payment service, etc., and all the services are connected via HTTP connection. If the order service needs user information, it will send a request to the user service via HTTP. Also, the database is split by domain as well, each service contains its own database.
Everything looks good, right? We split the app and database into small components. Now, we can scale a small instance easily and fast. If order service is the bottleneck of the system, we can add more resources to scale the order service instance. It seems to utilize the resources friendly. Also, we can deploy a single service directly without affecting other services. People are happy about that. It solves the problems that we talked about in monolithic architecture.
That’s all for today?
No. Definitely not.
Is it really the right way to create microservices? Look at the diagram below:
Apart from splitting the modules out, is there any difference? All components are tightly coupled together. The only difference is HTTP and local method invocation. If your whole system is like this, everything is tightly connected together, it is not really Microservices but Distributed Monolith in some sense. This architecture hasn’t utilized the benefit that microservices bring to us such as Loose Coupling and Cascading Failure Prevention. Now, if single action fails, the whole API call chain fails. All traffic going to the services in a synchronous way will make some services busy or even make it down if suddenly a lot of the traffics come and the service is not able to support that much. Tight coupling may cause different issues such as slow response speed, data loss, complete system break, etc.
I am not saying tight coupling is not good but if your whole system looks like this, you should review your architecture to see if the tight coupling is suitable for your use case and avoid the Single Point of Failure. Also, consider a loose coupling design if it is possible to adopt this design in your scenario.
Okay, that’s all for today. This time is for real.