📜 ⬆️ ⬇️

Microservices: please do not need


Illustration @alvaro_sanchez


For a while, everyone went crazy over microservices. It was impossible to open your favorite news aggregator and not see that some unknown company until now talks about saving its engineering department with the help of microservices. You may even have worked for the company yourself, which captured the excitement of tiny, magical small services that would solve all the problems of a large, neglected, full law code base.


Naturally, in reality everything turned out quite the opposite. When you look back at what happened, the vision is closer to 100% than when you look with hope into the future.


I want to talk about some important misconceptions and the pitfalls of the movement for microservices from the point of view of a person who worked for a company that was convinced of the idea of ​​the healing properties of microservices. I do not want the conclusion of this article for you to be "microservices == bad", but ideally I would like you to think about the problems when you decide whether microservice architecture is right for you.


What is "microservice" in general?


There is no perfect definition, but people who are promoting this area have been able to describe a good set of requirements for the system, according to which it could be attributed to the “microservice” architecture.


You can say it is not a monolith. In practice, this means that microservice works with only a small, as limited as possible task area. It performs a minimum of functions to achieve a specific goal in your stack. Here’s a more specific example: let's say the bank has a “Login Service”, and you certainly don’t want this service to have access to the financial transactions of your customers. You will take this area to some “Transaction Service” (bear in mind - it’s very difficult to give names).


In addition, people often assume that microservices must communicate with other services remotely. Since they are separate processes, and often run far from others, usually such processes communicate with each other over the network using REST or some other RPC protocol.


So far everything seems simple enough - you just need to wrap small pieces of the system in some REST API, and let everyone communicate with each other over the network. In my experience, there are 5 "truths" that people believe in, and which are not always true:


  1. The code will be cleaner
  2. It is easier to write modules that solve one problem.
  3. It works faster than monolith
  4. Engineers easier if you do not need to work with a single code base
  5. This is the easiest way to provide automatic scaling, and here is Docker somewhere involved.

Misconception # 1: Cleaner Code


“You don’t need to add a network constraint to justify writing better code.”


The truth of life is that neither microservices nor any other approach when modeling the technical stack is a requirement for writing cleaner and more supported code. Of course, once the moving parts are smaller, the ability to write lazy and ill-considered code is reduced. But it’s like saying that thefts can be defeated by removing goods from shop windows. You did not solve the problem, you just removed a lot of features.


A popular approach is to build architecture in such a way that logical "services" own parts of the domain. This is similar to the concept of microservices, because the dependencies that control the system will be explicit. And business logic will not fit into different angles. In addition, this approach does not entail an excessive use of the network and possible problems associated with this.


Another advantage of this approach is that it resembles Service Oriented Architecture, built on the basis of microservices: if you decide to go to microservices, then most of the work has already been done, and you probably already have a good understanding of the subject areas for proper separation of its parts. True SOA begins with a code, and continues over time at the level of the physical topology of the stack.


Misconception # 2: It's lighter


"Distributed transactions are never easier."


It may seem different from the outside, but most of the subject areas (especially in new companies that need to create prototypes, make pivots and generally redefine the area itself many times) cannot be divided into neat, clear boxes. Often, an arbitrary part of the system needs to get data about another part in order to work correctly. Everything becomes even more complicated when she delegates the operation of writing data to another part, outside of her subject area. When you have gone beyond your zone of influence, and you need to use other parts to store or change data, then you are in a country of distributed transactions .


When several remote services are involved in a single request, the complexity greatly increases. Is it possible to refer to them in parallel or need to be addressed sequentially? Are you aware of all possible errors in advance (at the application level and at the network level) that can occur at any time, at any part of the chain, and what will these errors mean for the request itself? Often, each of the distributed transactions requires its own approach to error handling. And to understand all the mistakes and understand how to solve them is a very, very big job.


Misconception # 3: It's Faster


"You can greatly improve the performance of the monolith if you add a little discipline"


This error is difficult to refute, because in reality we can often speed up a separate system if we reduce the number of tasks or the number of dependencies that are loaded, and so on.


But overall, this is not systemic evidence. I have no doubt that if you switched to microservices, the code isolated in these services could be accelerated, but you should not forget about the delays caused by network requests. A network is never as fast as internal communication, it is sometimes “fast enough”.


In addition, many stories about increasing productivity are in fact related to the benefits of a new language or a whole technological stack, and not just microservice architecture. If you rewrite the old Ruby on Rails, Django, or NodeJS application in a new language like Scala and Go (two popular choices for the microservice architecture), then the performance will improve, if only because of improvements in the performance of new technologies in general. But these languages ​​don't really matter if you call their processes "micro." They work faster because of simple factors like compilation.


Also, in most applications in startups, the net performance of the processor and memory is almost never a problem. Usually the problem is in I / O, and additional network calls only increase I / O.


Misconception # 4: Better for Engineers


When many engineers work in isolated code bases, then the syndrome "is not my problem."


It may seem that when small teams work on small pieces of the puzzle, everything will be easier. But in the end, this configuration can lead to problems.


The biggest problem is the need to run an ever-growing number of services for any, even the smallest change. That is, you need to invest time and effort to build and maintain a system where every engineer can run everything locally. Such things as Docker can simplify this moment, but someone will still have to maintain the configuration throughout the life of the project.


In addition, it complicates the writing of tests. To write a normal set of integration tests, you need to understand all the services associated with a particular operation, take into account all possible errors, and so on. It will take more time to understand the system than to develop the system. And although I will never tell an engineer that to understand a system is a waste of time, I still want to warn him against adding premature complexity.


And finally, this configuration creates social problems. Bugs can live simultaneously in several services and require changes at the level of several teams. They need to synchronize and coordinate their efforts. In addition, people can lose their sense of responsibility and try to push as many problems as possible to another team. When engineers work together on the same code base, the understanding of the system grows simultaneously with the understanding of each other. They are more likely to work on solving problems together, rather than being the kings and queens of small isolated principalities.


Misconception # 5: Scale Better


"Microservice can be scaled in breadth as well as a monolith"


Packing services into separate units and scaling them with, say, Docker is a good approach for horizontal scaling, without a doubt.


However, this can be done not only with microservices. The approach works in the case of monolithic applications. You can make logical monolith clusters that handle portions of traffic. For example, incoming API requests, front-end control panels and background tasks can be in the same code base, but it is not necessary on each machine to process all three types of requests.


The advantage here is the same as in the case of microservices: individual clusters can be configured depending on the load, and they can also be scaled individually in response to traffic spikes. Microservice architecture from the very beginning pushes to such an approach, but nothing prevents you from applying the same method for scaling a monolithic stack.


When to use microservices


“When you, as an engineering organization, are ready,”


I want to end this article with a discussion of when the right time will come to microservices (or, if you have already begun, how to understand if this was the right moment).


The most important thing on the way to a good, working microservice architecture is a simple understanding of your subject area. If you do not understand it, or are still trying to understand, then microservices will bring more problems than solutions. But if you already have a deep understanding, then you know the limits and dependencies, and the microservice approach can be the right step.


Another important point is your work environment, especially how it will look in the context of distributed transactions. If you are familiar with the paths of each category of queries in the system, and you understand where, how and why these paths may break, then you will be able to build a distributed model for processing queries.


In addition to understanding the environment, there is a topic of monitoring the environment. It goes beyond the discussion of microservice vs. monolith, but monitoring should be at the heart of engineering efforts. You will likely need a lot of information about different parts of the system to understand why one of the parts behaves badly or even generates errors. If you have a well-established system of monitoring components of the system, then you will be able to understand the behavior of the system during horizontal scaling.


And finally, if you actually demonstrate the benefits of your engineering organization and the business as a whole, then moving to microservices will help grow, scale, and make money. Of course, building interesting systems and trying new things is great, but in the end any company has the most important indicator. If you have to postpone the release of a new feature, which will bring money to the company, because of a post on some blog about "monoliths is bad," then you will have to justify this decision. Sometimes it's worth it. Sometimes not. Knowing when to insist and take time will help your reputation in the long run.


findings


I hope, now you have a set of conditions and questions that need to be resolved if someone offers a microservice approach. As I said at the beginning, my goal was not to prove that "microservices are bad." But jumping onto microservices without thinking about all the possibilities for details and questions is asking for problems in the future.


If I ask for my advice, I would look in the direction of "internal" services based on clean, well-defined modules in the code. They can already be brought to these services in the future, if the need arises. This approach is not the only possible one, and certainly not a panacea for bad code. But it will help you move forward faster than if you dig into microservices before the right one.


')

Source: https://habr.com/ru/post/311208/


All Articles