Original Title: Untangling Microservices, or Balancing Complexity in Distributed SystemsTranslation: Zhu Kunrong
The honeymoon period of microservices is over. Uber is restructuring thousands of microservices into a more manageable solution [1]; Kelsey Hightower is predicting that the monolithic architecture will be the future [2]; Sam Newman even stated that microservices should not be the first choice, but should be The last option is [3].
How is this going? Despite the promise of simplicity and flexibility in microservices, why have so many projects become difficult to maintain? Or is the final monolithic architecture better?
In this article, I want to discuss these issues. You will see some common design problems of programming microservices into a distributed big ball of mud-and of course, how to avoid them.
But at the beginning, let us first understand what a monolithic architecture is.
Monolithic architecture
Microservices have always been considered as a solution for monolithic application code. But is monolithic application a problem? According to the definition of Wikipedia [4], a single application is self-contained and independent of other computing applications. Is it independent of other applications? Isn't this what we pursue when designing microservices? David Heinemeier Hansson [5] pointed out the shortcomings of monolithic applications. he
Therefore, microservices are not "repairing" monolithic applications. The real problem that microservices need to solve is the inability to deliver business goals. Generally, teams fail to deliver business goals because of exponential growth-or worse unpredictability-the cost of making changes. In other words, the system cannot meet the needs of the business. The uncontrollable change cost is not the characteristic of the single application, but the characteristic of the big mud ball [6]:
The big mud ball is a messy structure, disorder, muddy, tangled wires and tape, a jungle of noodle codes. The system showed clear signs of uncontrolled growth, repetition, and temporary repair. The information in the system is chaotically shared among the system parts of many extremely long links, which means that most of the important information has become global or duplicated.
The modification and evolution of the complexity of the big mud ball can be caused by multiple reasons: coordinating the work of many teams, conflicts of non-functional requirements, or a complex business domain. No matter what, we often try to resolve this complex problem into microservices.
What is it?
The text "microservice" indicates that part of the service can be measured and its value should be minimized. But what exactly do microservices mean? Let's look at some common usages.
Micro team
The size of the first team working on service. And this scale can be measured by pizza. You heard me right. They said that if the team working on the service can be fed by 2 pizzas, then this is a microservice. I found this very enlightening. I once worked on a project and the team could be fed by a pizza... And I dare to say to anyone that this big ball of mud is a microservice.
Microcode library
Another widely used method is to design microservices based on its code base. Some people take this concept to the extreme, limiting the size of the service to a certain number of lines of code. In other words, the exact number of lines of code that can constitute a microservice has not been found. When this holy grail of software architecture is discovered, we will move on to the next question-what is the width of the editor for building a microservice team?
There is a more serious problem. A less extreme version of this method is more popular. The size of the code base is often used to determine whether it is a microservice.
Sometimes, this method works. Smaller code base, smaller business domain. Therefore, it is easy to understand, realize, and develop. Moreover, a smaller code base is unlikely to become a big ball of mud-if it happens, it is easier to refactor.
Unfortunately, the simplicity mentioned earlier is just an illusion. When we started to evaluate the design of a service based on the service itself, we ignored the core part of the system design. We forgot the system serving as the system constitutes .
"There are many useful and instructive ways to define the boundaries of a service. Size is the least important part."-Nick Tune
We develop the system!
We develop systems, not collections of services. We use a microservice-based architecture to optimize the design of the system instead of designing independent services. No matter what others say, microservices cannot and will never be completely decoupled and independent. You can't build a system with completely independent components! Now we look at the definition of "system" [7]:
- A group of objects or equipment that are connected and can be operated together
- A group of computer equipment or programs used together for a specific purpose
Services will continue to interact with other services to form a system. If you design a system by optimizing services, but ignore the interaction between them, you may end up like this in the end:
These "microservices" may be simple in themselves, but the system has become a hell of complexity!
So how do we not only deal with the complexity of the service, but also consider the complexity of the entire system for microservice design?
This is a difficult question, but fortunately, there was an answer long ago.
The complexity of the system perspective
Forty years ago, there was no cloud computing, there was no demand on a global scale, and there was no need to deploy a system every 11.7 seconds. But engineers still need to control system complexity. Although these tools are not the same as they are now, the challenges-and more importantly, the solutions-are similar and can also be used in systems based on microservices design.
In his book, "Composition/Structural Design" [8], Glenford J. Myers discusses how to use structured procedural code to reduce complexity. On the first page of the book, he wrote:
The topic of complexity is more important than simply trying to minimize the local complexity of a part of the program. A more important type of complexity is global complexity: the complexity of the global structure of the program or system (for example, the degree of relevance or independence of the main parts of the program).In our context, the complexity of each individual and the complexity of the entire system . Since the complexity of a local service achieve some ; global complexity are among the services interactions and dependencies defined.
So which complexity is more important-local or global? Let us look at the situation when only one complexity is concerned.
To minimize the global complexity is actually very simple. We only need to evaluate the interaction between any system components-that is, implement all functions in a single service. As we saw earlier, this strategy is useful in certain scenarios. In other scenarios, it can lead to the terrifying big mudball-possibly the highest level of local complexity.
On the other hand, we know very well what happens when you only optimize the local complexity and ignore the global complexity of the system-a larger distributed big mud blob.
Therefore, when we only focus on a certain type of complexity, it does not matter which one we choose. In a complex distributed system, the complexity of the opposite will skyrocket. Therefore, we cannot just optimize one. Instead, we have to balance local and global complexity.
Interestingly, the complexity balance described in the book "Composition/Structure Design" is not only related to distributed systems, it also provides insights on how to design microservices.
Translation to be continued...
Reference index
- Gergely Orosz’s tweet on Uber
- Monoliths are the future
- Microservices guru warns devs that trendy architecture shouldn’t be the default for every app, but ‘a last resort’
- Monolithic Application(Wikipedia)
- The Majestic Monolith - DHH
- Big Ball of Mud(Wikipedia)
- Definition of a System
- Composite/Structures Design - book by Glenford J. Myers
This article is from Zhu Kunrong's WeChat public account "malt bread, id "darkjune_think"
Developer/Science Fiction Enthusiast/Hardcore Host Player/Amateur Translator
Weibo: Zhu Kunrong
Station B: https://space.bilibili.com/23185593/
Communication Email: zhukunrong@yeah.net
Please specify if reprinted.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。