Microservices as the last resort?
Avenga Tech Comments
Microservices guru and author of several well recognized books about this architectural strategy, Sam Newman, shocked the world by saying that microservices should be the last resort when it comes to enterprise applications. He cites high costs without benefits, such as independent deployability.
And now, the phenomenon we use to call microservices is the default choice, which is shown in all the many surveys and conversations. It’s almost impossible to propose different kinds of architecture; the pressure towards microservices is so high.
Let us share our opinions about the reality and promises of the microservices architecture.
Jacek Chmiel, Director of Avenga Labs
It’s something that almost everybody (be it an architect or senior developers, etc.) has known for a long time already, but still refused to say in public. How do you do your microservices? With few exceptions most of them are a kind of distributed monolith. Either it’s a monolithic data store, or the lack of independent deployability, or the monolithic front-end.
Finding true microservices solutions in enterprises are possible, but quite rare.
From my perspective, it’s another interesting trend with a very similar pattern, just as in the past. The promise, as always, was really good and the reality, as always, was much more difficult and costly than anticipated and close to impossible.
Let me recall some older trends like SOA, NoSQL, DDD, agile, TDD, and BDD.
The key rule is always the same: if you want to benefit from the good that a new way is bringing — be prepared to pay the full price, and the full price will be much higher than you think it is right now.
But in reality people tend to optimize by paying 80% of the effort required, and then benefit from let’s say only 20% of the benefits, because of “almost” having the thing they wanted to have. It’s like having ‘almost’ a car — yes a car, but without the steering wheel (for less techy readers). So actually they are in an even worse position than before, because the cost increase cannot be turned back.
For instance in the case of a microservices trend, people took some elements (decomposition of business logic layer and APIs), paid the visible and invisible price (additional effort, devops nightmares, learning curve, more people required to do the same job, performance drop, latency issues and as bonus: data inconsistency), and were unable to benefit from the key promises, such as better resilience and faster changes due to the lack of independent deployability. And that actually would require even more effort.
The #1 benefit that the majority agrees on, is the ability to make independent teams work in parallel, so making things faster. “Maybe it’s all a failure, but at least we can do things in parallel” they say, which doesn’t necessarily mean faster.
Microservices are not a cure for improper communication between the team members and the teams, product owners and stakeholders. Sometimes, it looks like multiple silos focused on their microcosmoses and blaming each other when the bricks (microservices) didn’t fit in the end and overlapped with duplicated functionality. In the case of good communication, the microservices are to some extent irrelevant; the same goals can be achieved with modular architecture.
Distributed monoliths renamed as microservices are here to stay. Containers for the masses (Docker) wouldn’t be here without this movement as well as other useful technologies and patterns. It’s good that software development is more than just a fashion business and each revolution results in technologies and knowledge that are useful now and in the future.
Combining existing solutions instead of reinventing the wheel is a task that software architecture has always tried to solve. To use the Web for encapsulation was one of the ideas of SOA. With REST and the term “microservices”, these services have become as small as possible.
A developer is able to create lots of microservices with small tasks. But splitting services as tiny as possible, brings more problems than solutions. At the end, the responsibility is gone.
But how to combine flexibility and responsibility?
All services should be self containing deployable items with a value and responsibility.
Value in this context means, capsulated services in your product. Responsibility means shipping a product to your client and controlling the quality (logs + monitoring). Bundle them to a “monolith” with backend for frontends (BFF) and take responsibility for your product.
In general, you cannot solve problems — you swap problems. Choosing a “solution” means that you choose more likeable problems. The microservice architecture comes with a lot of new problems, and many of them are not likeable at all. The foremost of them is increased complexity. Complexity is a lure for some developers, but a fear for many others. Interestingly, microservices emerged as a way to better cope with on-going growing complexity. If you find that microservices make your setup more complex, you are “solving” a problem that you don’t have. The microservice pattern is a wonderful tool, but it should not be applied generally. Solve problems that you have, and do so with solutions that your team can handle.
Microservices, if done properly, can be an incredibly powerful architecture. However the “if done properly” quantifier cannot be skipped from the previous sentence. And doing microservices properly is not an easy task.
Therefore even though it sounds a bit extreme from the mouth of Sam, I can understand his message.
There are no ultimate solutions for the problems we’re all faced with. Cloud is not an answer to all hosting related issues of modern IT. Sharepoint is not the ultimate solution for collaboration platforms. Slack is not the only solution for an instant messaging system (right Microsoft? ;)).
When working on a project, we should first invest all our efforts into understanding the real needs, requirements, and constraints of a given organization. Then we should cold calculate the pros and cons of a given architecture.
By no means, should we start with the architecture/technology/framework/programming language.
And for me, that’s what Sam had in mind, putting microservices as the last choice for enterprise applications.
Every conversation about microservices should begin with defining what sides are really put into “microservice”. Microservices are like sex in high school — everybody swears they are doing it, but no one actually knows what it is.
Nowadays, tech trends force you to build comparably small, independently deployed, and single (almost) purposed applications using Kubernetes, Serverless, Java and trendy frameworks like Quarkus, and Micronaut. Even more, thought-leaders like Netflix and Uber are well-known for using and promoting microservice architecture.
So, are microservices good or bad? It’s neither. It is what it is. The “Microservice” approach is just an evolutionary step in tech. You can easily have a bad microservice application and a good monolithic app. But you can easily have it vice versa. I can agree with Sam that microservices shouldn’t be a default approach for every system; nor should any architecture.
Think first, follow best practices and write tests.