In simple terms, it means dividing the components of the software into standalone individual SaaS modules called services, which expose a simple API for other modules or services. Any such service may depend on other services (upstream) and in turn have other services depend on it (downstream).
Each service in a microservices system encapsulate a fine-grained responsibility and is only loosely coupled with other services. It only communicates with other services via APIs (preferably REST).
There are certain very appealing advantages of having such an architecture:
- It follows Unix philosophy of promoting composability over monolithic design. Unix philosophy requires the software to do one thing and do it well or in other words design programs as tools which can work with other programs as in a pipeline to solve a larger problem. Microservices is a realization of that vision in the large.
- Scaling becomes somewhat easier since we need to scale just the bottleneck services rather than the whole system. As a result, hardware requirements for the whole system may be smaller.
- Making small changes to a part of the system without effecting other services become much easier.
- Since each service is a self contained piece, dependencies on external libraries are reduced so refactoring or removing dead code is less risky and easier to do.
- Individual services can be built and deployed independently – whole system need not be shutdown to make a minor change. This bestows higher availability on the system.
- The system becomes more fault tolerant – if a sub-system fails, that can be restarted or bypassed without effecting other parts.
- Since services communite via APIs, each microservice can be implemented in a different language (ployglot codebases) as per the strength of the team developing it.
The microservices architecture requires a lot more dev work to make them successful.
- To make the system as a whole work, we need better dev practices. The most important is continuous integration testing to catch integration bugs. Each service gets tested by the respective dev team but testing the system as a whole should be a priority as well.
- Debugging becomes harder since multiple services may have to be investigated which may lie with multiple teams – deflection of responsibility is a real possibility.
- Developers may lose the holistic picture about how each piece (service) interact in a cascading network with others. They commonly only worry about only upstream and may be downstream services but rarely the whole system. This can have negative consequences on performance or debugging.
- Most importantly, microservices doesn’t reduce the essential complexity of the system and moreover distributes them which means designing it well requires more skill.
- Such a system requires a lot of automation in devops like automated one-click deployments, automated server configuration and management.
- Microservices also need solid server monitoring strategies. The individual services should be monitored at several levels like network, server resources and application correctness.
Other than the the pure technical merits and demerits, there are also some social aspects of microservices architecture. As Conway’s law states organization structure anyway gets reflected in the software architecture. Microservices architecture is a way to one up Conway’s law and forces us to design an organization which suits the technical architecture.
Also, small independent teams allows the developers to work more independently and spend less time communicating and meeting and more time coding, which is of course good for overall productivity.
I worked at Amazon which has been a pioneer in Microservices and distributed computing and which was my introduction to this architecture. Since then, I have built and maintained several such systems.
I think, microservices are not a silver bullet for scaling which it is often made out to be currently. It is not for every application and it certainly should not be the default choice for anyone building a software system from scratch. Rather, it is one of the tools, and a very powerful one, in the architect’s arsenal to wield when needed.
- Building Microservices by Sam Newman and its review by Adam Tornhill
- Erlang is a language especially suited to building fault tolerant SOA.
Addendum: There is some debate about the distinction between SOA and Microservices and the consensus seems to be that Microservices are independently deployable, have separate DBs and don’t have a ESB. However, in my personal experience several companies are implementing MSA and calling it SOA and vice versa too. I like to think of MSA as a natural and minor evolution of SOA.