Microservices architecture has been seen as a silver bullet to decouple any sort of system without much effort and enhance the maintainability of that system as well. It does come with great potential. I am very careful with my words and hence I say "potential". It is great only as long as it is properly designed and implemented or else it will soon become a maintenance nightmare and a weird piece of code which is almost randomly demarcated into services making it a "poorly written novel by a great writer" which is a bigger disaster. But before we jump to what all things should be kept in mind to avoid such a disaster, let's quickly have a look at what a microservice architecture (MSA) offers us.
The key benefits that a well-drafted MSA offers are as follows :
- Loose coupling and high cohesion of code. In simple terms, "related" items should be together but "updating" one item should not be a mess for other items. If well designed, MSA achieves this brilliantly.
- Avoiding SPOFs (Single point of failure).
- Separate scaling of services. Instead of scaling all the services together and using precious resources, we may scale only needed services and save resources and cut costs.
- Better readability of code, and ease of maintenance. Clear separation of concerns and the ability for a team to work independently on the "larger project" by individually contributing to the "smaller project" or the microservice.
- Great for Agile development and incremental releases.
- Flexibility in terms of choosing a tech stack. One MSA could be in Jave while the other can be in Python or anything else as long as they have a way of communicating. Allows us to choose the best "tools" for the task.
- Easy extensibility and deployment ease. We can add a new microservice without affecting the existing code much and deploy individual microservice instead of the whole system. This also helps in version control of each "piece separately" ensuring higher availability.
- If you are migrating from a monolith towards an MSA, how do you define which part of the code should reside in which microservice? The demarcation might seem obvious at first but is a very difficult job to do and if done wrong, you might have 'n' monoliths after splitting your '1' monolith. The decision is also complicated because each piece that you decide to split may now need to be contacted via a network call which is expensive and has limitations.
- How do you do failure handling? MSA does remove a SPOF but it introduces MPOFs (multiple points of failure) if not written well. This can be like cancer spreading to your whole system. More the number of moving pieces distributed and scaling independently, the more the chances of one of them failing (In the real world, failures are inevitable. There is no way you can have a foolproof system. If you can, you would be really rich!).
- How do your microservices interact with each other? RPC or HTTP or web sockets or something else? Do they interact directly or via queues? Do they store state or are all stateless? These complications start adding up.
- The addition of new components (load balancers, circuit breakers, queues etc) is a costly affair in terms of time and money.
- How do you avoid "over-engineering" and "engineering activism". It is very easy to get carried away as a team and start making too many microservices or try making the microservices too perfect or trying to achieve too much decoupling etc. MSA is not a magic wand which will get rid of all software development problems and we must understand our limitations and do a proper cost-to-benefit analysis before over-investing in this. There should and there is a saturation point.
Comments