Microservices sounds like a pretty slick name, but in fact, it isn’t all that complicated. Microservices are, broadly speaking, all about providing APIs and collaborating between those APIs.
Microservices are a specialisation, a refinement and an evolution of Service-Oriented Architecture (SOA). It is a specific approach for how to do Service-Oriented Architecture better. It has arisen, not due to any academic theories, but from an analysis of lots of real world projects, and takes all the best approaches of SOA learnt from that experience.
The reason you don’t hear much about Service-Oriented Architecture any more is that it was actually a big embarrassing failure. For all its promises, very little actually materialised. There was a lack of consensus on how to do SOA well, there was a lack of guidance on service granularity, SOA doesn’t talk about how to ensure services don’t become overly coupled, and there were too many attempts by vendors to lock you in.
Microservices provides architectural guidance to ensure better choices are made when divvying up an application for better maintenance, flexibility, scaling, resilience and reuse. The idea is to break up large all-encompassing monolithic applications into a whole lot of little services. The smaller the services are, the more the benefits around interdependence are maximised. It also allows functionality to be consumed in different ways for different purposes. The downside is that extra complexity emerges from having more and more moving parts, so we have to become a lot better at handling those complexities.
Microservices aligns well with existing software development methodology, technologies and processes. By splitting an application into a bunch of services, and forcing them to communicate with each only via network calls, it allows each service to be treated like its own bounded context, a concept from Domain Driven Design. Each service also needs to have a Single Responsibility, to be a completely separate entity, to be able to change independently of each other, and to be deployed by themselves, without requiring their consumers to change.
By managing a bunch of separate services, each component can be scaled separately. Too much demand for one service? Spin up another process of that service. They can also be run on multiple separate machines. The system is also much more resilient, as the failure of a single service does not bring the entire system down.
And you are not constrained by the technologies that they run under either. Because there are lots of little services, they work well in the cloud, where the architectural approach can be so closely correlated to an almost immediate cost saving as you reduce compute time for elements that don’t require much resources and increase compute time for the bottlenecks in the application.
Large organisations may have a large number of microservices, and because each microservice is entirely independent, they can be coded in isolation as well. The Microservice approach allows us to divvy up the services so that we can hit the sweet spot between team size and productivity. A good starting point for how big a microservice should be is around 2 weeks of work for team of around 8, so that fits really well in with Agile sprint size as well. You can also have the entire team for a single microservice collocated, while another team may be working on a complementary microservice collocated elsewhere.
There are also other benefits from using the microservice approach to application construction. Teams that follow that approach are actually quite comfortable with completely rewriting services when required, and choosing alternative technologies with the ability to make more choices on how to solve problems. They also have no problem replacing services that they no longer need. When the code base is only a few hundred lines of code, it becomes difficult to become emotionally attached to it, and the cost of replacing it is pretty small.