The Famous Mythical Microservices
Disclaimer: Please don’t continue if you are easily discouraged by cynicism
The term microservices has been around several years now. In the beginning it was a way of creating distributed systems that are more agile and less monolithic than the old-school SOA architecture. SOA was about connecting big monolithic systems with big and robust ESBs and batch jobs. Whereas in microservices you would have smaller and leaner components with more p2p connections and dumb channels.
But nowadays I really dislike the terms Microservices or Microservices architecture. I rather say, a distributed architecture. I don’t like it because when people started to follow the footsteps of the pioneers in this kind of architectural design, they also started overthinking, overexplaining, overdesigning it and narrowing down it’s definition as a justification for their own expertise on the field.
To me the path of microservices resembles to the one of agile methodologies. I can still see agile coaches and scrum masters nowadays having certificates and become experts on the field. Whereas agile never meant to be a concrete process.
Please watch Dave Thomas’ talk, who is one of the original authors of The Agile Manifesto: https://www.youtube.com/watch?v=a-BOSpxYJ9M and see how cynical he is about what the whole agile industry become.
Microservices are very similar in this way. So let me explain what my problem is with this term.
Microservices as an evolutional peak
One of my problem with microservices is it is often presented and seen as naturally the best and greatest design. It’s the top of the software system design evolution. You almost feel bad if you are not designing your software in microservices design, because you know it will then be subordinate and pathetic.
Once I was working on a greenfield microservices project that had a formal design in SysML from hour zero. One of the managers was looking at it and said: it’s good but it is microservices architecture, so there should be more services. There was only 8 services carefully decomposed based on the domain model and functional scenarios. Is it really the right approach?
The reality is that microservices made people aware about some good design decisions and patterns, and was an answer to an organizational problem. It’s never about microservices being right and everything else being wrong.
Microservices are romanticized
Always take big microservices success stories with a pinch of salt
When I am watching a talk from an engineer from one of the top tech companies or startup unicorns e.g. Netflix, Facebook, Uber, it always leaves me with a feeling: wow, that is real complex engineering work, it is really well thought through, really scalable, fault tolerant with high throughput, low latency and what not. I will never have a chance to create such great microservices design. — Or at least that’s what I tend to think
In a 45 min. talk we usually only see the achievements, and only a tiny fraction of the whole story. They don’t really talk about the path to get there, and all the struggles. They don’t mention the burnt engineering hours that come from the inefficiencies of big organizations and the inefficiencies of agile methods and communication between distributed teams. If someone has ever read about what life is like in big tech companies, she knows that there are often multiple teams working on the same problems not even knowing about each-other.
These talks don’t mention whether they can efficiently provision their cloud infrastructure so no money is wasted on idle services, or if they can properly make capacity measurements so they don’t oversize their infrastructure.
These talks are effectively comparing penis size: how many projects and services do they say? 200, 2 000, 2 000 000 services? Are they even separate software projects or instances, who will ever know?
They usually don’t mention the biggest problem of distributed architecture, which is data integrity. You can run a huge microservices architecture, and have half of the services always reconciling data because integrity just doesn’t exist in the system.
Today everything is microservices
The meaning of this term has inflated. Do you have two services that communicate through REST? Congratulations, It’s microservices! Are they running in docker container? It’s microservices! Do you have a message queue? It is then super-microservices! Are you using some distributed key-value store? It is uber-microservices!
The term microservices architecture has been inflated by tech leads and hiring managers who are trying to sell their projects to new hires
… or just sell their own expertise on the field
I will go further: The more new, but specialized, however complex technology you are using (e.g. Cassandra, Kafka, K8s), the more likely you can claim having microservices expertise. No matter if you ever needed it in your project.
The easiest thing about microservices is criticising other people’s microservice
Some arguments are:
You have separate DB schemas per service, but they are all running on the same DB instance, so it’s not really microservices, because if your DB instance fails, all your services are brought down.
Are you periodically pulling information from another service, and don’t use event sourcing? That is really not microservices-style!
Are you not using asynchronous eventing, but your whole business transaction is synchronous? Just wow, in a microservices style you should use eventing!
What? Are you consolidating your technology stack and do everything in Java? Are you nuts? In microservices you can do every service in any programming language!
Are you using monorepo? That means tightly coupled code, this is a monolith then!
These are all false arguments, that take only one small aspect and disregard the big picture.
On the technical side microservices is just distributed applications
I rather call them distributed applications. The term microservices is just too constraining. It implies one correct architectural design but it’s usually never fully achieved.
If an immaculate microservices design is not achieved it may be labeled as a “bad design”, although it may have never been the intention to have all the microservices traits in a system even from the beginning. So is it a bad design then? I don’t think so.
A distributed application can have a couple of motivations e.g.:
- better performance tuning
- faster releases
- easier maintenance
Distributed applications inherently consist of many different executables or components. Once services are decomposed, performance tuning is easier since lower performing services can be localized, and each service can be either horizontally or vertically upscaled.
Faster releases is not so straightforward, we rely on the losely-coupled nature of distributed systems. But without any further considerations, naturally, components in distributed systems are still tightly coupled (think about RPC). Easier maintenance is just the result of losely coupled components.
The only valid definition of microservices is being an organizational pattern
We, technical people tend to forget about organizational questions. Actually the main motive of microservices was not technical at first: it was making large-scale problem domains more manageable on both organizational and technical level.
A big problem domain is decomposed into smaller chunks. These chunks can be assigned to teams who take full ownership and responsibility about delivering that part of the software. These teams are called cross-functional (or delivery) teams. Once each business function is assigned to a team, a large scale project becomes more manageable. People who oversee the big picture don’t need to care about the details. Small technical details can be managed within each teams.
If we take into account Conway’s law, this organizational pattern naturally implies a technical architectural style where services, that are managed by different teams, have stronger boundaries. They are more cohesive and less coupled from other services, which is one of the definitions of microservices.
From this perspective the question arises: if we only have a team of 25 people is it possible to create a microservice architecture?
So how should we think about microservices?
I don’t know the exact answer. What I know is I don’t want to fall to the fallacy of arguing about why some systems are not real microservices because they lack some common traits. Neither I want to call a distributed application a microservice architecture because it consists of two tightly coupled services that communicate via MQ and use CI and CD.
Maybe we should just try no to label systems as microservices architecture.
On the technical level, we should think of it as an architectural style that facilitates better performance tuning, faster releases, easier maintenance of individual components without redeploying the entire software system, and without going into concrete technical details.
We can probably also say that microservices collect some common design patterns, but with an emphasis on that these patterns were only categorized and not invented by microservices.
On the organizational level, it is a style that facilitates the decomposition of business functions and assign teams to those business functions. These teams then take full ownership of their domain. This creates big software systems manageable.
I had a chance to do microservices in a company with 25 engineers, and then with about 4000 engineers. It’s interesting to see as the scale grows how microservices just really is an organizational question, where technical questions become guidelines and the implementation details are left to the individual teams.
Sometimes it’s good to go back to the roots and revisit some classics, such as Martin Fowler’s post about microservices. I like this post because it really talks about paradigms and not concrete patterns. https://www.martinfowler.com/articles/microservices.html