The discussion on microservices has exploded recently. It’s been heralded as the future. But is it really so new, or something more familiar than we think? Well, let’s start by setting the scene; what are microservices? Unfortunately, there is no universal and unique definition. In the most generic way possible, this is an “architectural style”, so it can be implemented in different flavours, and can be defined in many different ways. I personally think that the definition of Martin Fowler is the most clear and exhaustive:
“In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.”
I like this definition because it captures some of the key features that the industry tends to agree on:
- A microservices architecture is the result of a decomposition of a single application into a suite of smaller services.
- Every microservice is a stateless, isolated and independent process.
- They communicate with each other using open protocols (such as REST/HTTP, messaging).
- They can be written using different languages / frameworks.
- Each microservice encapsulates a specific business capability.
- Every microservice must be independently deployable, replaceable and upgradeable.
- They need a bare minimum of centralised governance.
- They must be easily scalable.
Despite the industry interest in microservices at the moment, they aren’t an entirely new concept; we’ll see later on that microservices are actually one of the many ways to implement a SOA architecture, focusing on a few specific patterns.
In general, explaining microservices is easier when making a comparison with the traditional “monolithic” applications…
Once upon a time: the monolith
Way back in the “traditional” web applications of the 90s and 2000s, we would probably see something like the above: a typical MVC structure where the services are accessing data from a single centralized RDBMS, which is probably shared by many other applications across the entire enterprise.
The services in this context are better described as “libraries”, i.e;
- They are part of the application
- They don’t have a very clear interface definition (as they don’t need it)
- They call each other using proprietary and closed or heavy protocols
- They share the same data
- And, most likely, they won’t be very reusable outside the context of this application.
The controller layer is responsible for invoking the services and rendering the data on the front-end, serving only one type of client (typically a web browser) - mobile apps and other devices weren’t a priority at the time.
From the deployment point of view, the whole application is packaged into a single artefact (e.g. a WAR or EAR), and the deployment team is responsible for deploying it across environments (CI, CD and DevOps were not a thing back then!). This means that a single change in one of the libraries implies a redeployment of the whole application, and worse, that a problem at the end of the pipeline can block the entire release, preventing many other changes to go live. When the application grows in size, the code base may be split in different repositories, and different teams may be responsible for different parts of the code. But the deployment still represents a potential bottleneck.
The application above is very likely to be implemented using a specific language or framework. This decision was made at the design phase before the application was implemented, and now moving to a different technology stack is unrealistic; who’s going to pay for that?
Finally a note on the actual development team; a large codebase cannot be digested from a single team, and when the team becomes too big the maintenance becomes more difficult. I’m a fan of Amazon’s “two pizza rule” when it comes to development teams; according to the rule, you should never have teams so big that two pizzas couldn't feed the entire group.
So that’s the history of the monolith. But why are microservices a different approach, and what benefits can they offer us? I’ll be diving into that in next week’s blog post.