Microservices and Monoliths

A colleague wrote a great article on microservices, to which I wrote an extensive comment. I will take the liberty of expanding and supplementing my comment, transforming it into a full-fledged article.

I completely agree with the theses from the mentioned article about the fact that 90% of typical arguments about the advantages of microservices have nothing to do with microservices:

  • The ability to write in different languages ​​- for 50 years now, hundreds of monoliths have been written in different languages.

  • Shit code in a microservice will not stop being shit code.

  • Stateless monoliths scale as well as microservices

and so on.

I also completely agree that microservices introduce a sufficient number of standard complexities:

  • Distributed data modification often without ACID guarantees

  • More complex debugging

  • Performance sag

and so on

But microservices have one key advantage – deploy fast due to the reduction of the deployment unit. Let's figure it out.

Let's take a classic monolith that's been around for 20 years. Let's say it's written in dotnet and it's one solution with a hundred projects that are assembled into one big container at the output (docker was added 5 years ago). 5-7 teams work on this solution, each of which has a manager, a backlog, and a business customer. All of this is in one repo and some kind of feature branching is used: each user story is done in a separate branch that is merged into the development, where releases are tagged.

For such projects, a release cycle of six months is still good. And the main difficulty here is the process, not the technology. First, you need to synchronize all the teams so that the code is stable by the release date. Second, you need to do a full regression of such a monolith – and this is a code freeze, several weeks of hard work by QA engineers, fixes, etc.

Now let's look at this from the business's point of view. Business usually wants its requests to be made yesterday. But here it turns out that the implementation of the minimum request must be waited for half a year. Naturally, this causes discontent.

How can the process be optimized? Obviously, by reducing the deployment unit. The release cycle of a small deployment unit can be dramatically reduced by minimizing the number of people involved, the amount of testing, etc. As long as the changes are encapsulated in a deployment unit.

And here come microservices. The minimum deployment unit. Microservice is developed by one team. No approvals for rollout. Regression testing is done in half a day. And as a result – a release every 2 weeks. Business sees the result right away.

But as usual, there is a price to pay for this. The price for a quick release of each individual microservice is a huge pain in the ass when changing a contract. If we take the described monolith, then all contracts are inside one solution. Auto-refactoring tools allow you to change contracts as you like within one minute. If contracts are not domained correctly somewhere, the solution build will fail.

In the case of microservices, this is, to put it mildly, not the case. Each microservice has its own release cycle. And if the team of microservice A changed the contract, then the team of microservice B (which calls microservice A) has its own plans, its own tasks, etc. Team B, which also pulls the microservice of team A, has its own history. And in practice, microservice A needs to support 2 versions of the contract, the old and the new, until clients switch to the new one. This can take months, and a new, third change to the contract is already in the plans of microservice A. Supporting 3 versions of the contract is not a good idea. In real big businesses (Netflix, for example), there are hundreds of microservices that call each other as they please. And again, everyone has to agree on any change in the contracts, write letters that “in 3 months we will stop supporting version 1 of the contract, whoever did not have time to switch to version 2 is not our fault.”

From which it follows that contract stability is the basis for the success of a project with microservices. And contract stability is achieved by correctly dividing the business domain into microservices. Correctly dividing the business domain into microservices is achieved by experience working in the business domain.

Something like that, let's sum it up.

Microservices are needed to speed up the release cycle in large and unwieldy systems. It follows that if there are no and are not planned problems in long release cycles – you do not need it. If you split the domain into microservices incorrectly, there is guaranteed to be a lot of pain with the cooperation of microservices. Start with a monolith. It is much cheaper to experiment with the responsibilities of modules and refactoring contracts between them. If you are already at the point where the release cycle does not fit into business expectations – a well-structured monolith, in which the division of responsibilities between modules and their communication has already been tested, is easily broken into microservices.

And yes, microservices are about process and deploy fast, and only secondarily about technology.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *