Microservices have become very popular in recent years. Many system research and development are considering adopting microservice architecture. At the same time, with the development of Docker container technology and DevOps development and operation integration and other related technologies, microservices have become It is easier to manage, which creates favorable conditions for the rapid development of microservice architecture.
On the road to implementing microservices, splitting services is a hot topic. According to what principles should we split the existing business? Is it better to break it down into smaller pieces? Next, let’s talk about the strategies and principles of service splitting.
Only by not forgetting your original intention can you achieve success.
Before introducing how to split, we need to understand what the purpose of splitting is, so that we will not forget the original purpose during the subsequent splitting process. The essence of splitting is to simplify complex problems. So what complexity problems did we encounter in the monolithic architecture stage?
First of all, let’s recall why we chose a monolithic architecture in the first place. When many projects are just started, we just hope to build the project as soon as possible so that the product can be put on the market earlier for quick verification. In the early stages of development, this architecture did bring great convenience to development and operation and maintenance, mainly reflected in:
However, as more and more functions are added, the size of the development team becomes larger and larger. The shortcomings of the monolithic architecture are slowly manifesting themselves, mainly in the following aspects:
In the early stages of a product, the monolithic architecture should be given priority. Because in the face of a new field, it is difficult to have a clear understanding of the business at the beginning. It often takes a period of time before it can gradually stabilize. If the separation is too early, the boundary separation will be unreasonable or too detailed. On the contrary, Will affect productivity. Many times, it is much easier to gradually divide services from an existing monolithic architecture than to build microservices from the beginning. At the same time, the company's products have not been verified by the market and may fail, so the risk of this investment will be relatively high. In addition, when resources are limited, many advantages of adopting a microservice architecture cannot be reflected, and the performance disadvantages will be more obvious. As shown below. When the business complexity reaches a certain level, the cost consumed by the microservice architecture will show its advantages. Not all scenarios are suitable for using the microservice architecture. The division of services should be carried out gradually and continue to evolve. In the early stages of a product, when the business complexity is not high, a monolithic architecture should be adopted as much as possible.
As the company's business model is gradually verified and the products are recognized by the market, in order to speed up the iteration efficiency of the product and quickly occupy the market, the company begins to introduce more development students. At this time, the complexity of the system The degree will become higher and higher, and there will be a contradiction between the single application and the team size, and the research and development efficiency will not increase but will decrease. The intersection in the above figure shows that the business has reached a certain level of complexity, the single application can no longer meet the needs of business growth, and the R&D efficiency begins to decline. This is the time to consider service splitting. This point needs to be weighed by the architect. When we know when to split, can we implement it directly? No, the implementation of microservice splitting requires the preparation of supporting infrastructure in advance, such as: service interface design (description), registration center, microservice framework selection, service monitoring, service tracking, service governance and other basic components , each of the above components is indispensable, and each component includes many technologies, such as: continuous integration, container technology, continuous deployment, DevOps and other related concepts, as well as talent reserves and changes in concepts. Microservices are not only an upgrade of technology, but also a change in development methods, organizational structure, and development concepts.
When to split microservices, the overall summary is as follows:
1. The internal functions of a single service have high cohesion and low coupling
That is to say, each A service only completes the tasks within its own responsibilities, and leaves functions that are not its own responsibilities to other services.
2. Closure Principle (CCP)
The closure principle of microservices is that when we need to change a microservice, all dependencies are within the components of the microservice. There is no need to modify other microservices.
3. Principle of service autonomy and interface isolation
Try to eliminate strong dependence on other services, which can reduce communication costs and improve service stability. Services are isolated through standard interfaces, hiding internal implementation details. This allows services to be independently developed, tested, deployed, and run, and delivered continuously as service units.
4. The principle of continuous evolution
In the early stages of service splitting, it is actually difficult to determine what the service will be split into.
From the words microservices, it seems that the granularity of services should be small enough, but too many services will cause problems. The rapid growth of the number of services will lead to a sharp increase in the complexity of the architecture, such as development, testing, operation and maintenance. It is difficult to adapt quickly, which will lead to a significant increase in failure rates and reduced availability. If it is not necessary, it should be gradually divided and continuously evolved to avoid explosive growth in the number of services. This is equivalent to the effect of grayscale release. Take out a few that are not important first. The function can be split into a service for testing. If a failure occurs, the impact of the failure can be reduced.
5. The process of splitting should try to avoid affecting the daily function iteration of the product.
In other words, the service-oriented split should be completed while iterating product functions. For example, prioritizing the separation of relatively independent boundary services (such as SMS services, etc.), starting from non-core services to reduce the impact of splitting on existing businesses, and also giving the team an opportunity to practice and trial and error. At the same time, when two services have dependencies, the dependent service will be split first.
6. The definition of service interface must be scalable
After the service is split, since the service is deployed as an independent process, the communication between services is no longer a process Internal method calls are instead cross-process network communications. Under this communication model, the definition of the service interface must be extensible, otherwise unexpected errors will occur when the service changes. For example, the interface of a microservice was upgraded from three parameters to four, which caused a large number of errors to the caller after it went online. It is recommended that the parameter type of the service interface be an encapsulated class, so that if you add parameters, you do not need to change the signature of the interface. , and just add fields to the class.
7. Avoid circular dependencies and two-way dependencies
Try not to have circular dependencies or two-way dependencies between services. The reason is that the existence of this situation shows that our functional boundaries are not clearly defined. Or there are general functions that have not been implemented.
8. Phased merger
As your understanding of the business domain gradually deepens or the business logic itself changes significantly, or the previous split was not considered very Clearly, the service boundaries after the split have become increasingly confusing. At this time, it is necessary to reorganize the domain boundaries and constantly correct the rationality of the split.
At present, many traditional monolithic applications are being upgraded to microservice architecture. If the granularity of splitting is too fine, it will increase the complexity of operation and maintenance, and if the granularity is too large, it will not be effective. So what should be done during the transformation process? What about balanced split granularity?
Bow and Arrow Principle
Balanced splitting granularity can be weighed from two aspects, one is the complexity of business development, and the other is the number of people in the team size. As shown in the picture above, it is like a bow and arrow. Only when the business complexity and the number of team members are large enough, will the sword of service split granularity fly further and exert its greatest power. For example, for e-commerce products and services, when we separate the products from large entities, as far as the products and services themselves are concerned, the logic is not complex enough for 2 to 3 people to maintain. At this time we There is no need to continue to break down the products and services into more details, but as the business develops, the business logic of the products becomes more and more complex, and may serve multiple platforms of the company at the same time. At this time, you will find that the problems faced by the products and services themselves are related to The problems faced in the monolithic architecture stage are basically the same. At this stage, we need to split the products into more fine-grained services, such as: inventory services, price services, category services, basic product information services, etc. Although the business complexity has been met, if the company does not have enough manpower at this time (recruitment is not timely or there are many employee changes), it is best not to split the service. Splitting will cause more problems due to insufficient manpower, such as R&D Efficiency drops dramatically (one developer is responsible for a mismatched number of services). Another question arises here: How many development and maintenance does a microservice require? Is it more rational?
The Three Musketeers Principle
Why is it more rational to assign one service to three people? Instead of 4, not 2? First of all, in terms of system scale, if 3 people are responsible for developing a system, the complexity of the system is just enough that everyone can fully understand the entire system and be able to divide labor; if 2 people develop a system, the complexity of the system is not enough , developers may feel that they cannot reflect their technical strength; if 4 or more people develop a system, the complexity of the system will not allow developers to understand the details of the system deeply.
Secondly, from the perspective of team management, 3 people can form a stable backup. Even if 1 person takes a vacation or is transferred to another system, the remaining 2 people can still support it; if there are 2 people, the remaining 1 person will be under great pressure after transferring 1. ; If it is one person, this is a single point. The team has no backup, which is very dangerous in some cases. What if this person is on vacation and there is a problem with the system? Finally, from the perspective of technical improvement, a technical group of 3 people can not only form effective discussions, but also quickly reach consensus; if there are 2 people, there may be situations where each other insists on their own opinions, or the two people have insufficient experience. Design defects; if it is one person, because no one has technical discussions with him, he is likely to fall into a blind spot in thinking and lead to major problems; if there are four or more people, some of the participants may not participate seriously and just complete the task. The principle of "Three Musketeers" is mainly applied to the microservice design and development stage. If the microservice has been relatively stable after a period of development, is in the maintenance period, and does not require too much development, then on average one person maintains one microservice Even a few microservices will do. Of course, considering the issue of personnel backup, it is best to arrange for two people to maintain each microservice. Each person can maintain multiple microservices.
**In summary, the splitting granularity is not as fine as possible. The granularity needs to comply with the bow and arrow principle and the three musketeers principle. **
The splitting strategy can be considered according to functional and non-functional dimensions. The functional dimension is mainly to clearly define the boundaries of the business. The non-functional dimension mainly considers six points including: scalability, reusability, high Performance, high availability, security, heterogeneity. Next, we will introduce it in detail.
1. Functional dimension
The functional dimension is mainly to clearly define business boundaries. The main design method used can use DDD (that is, domain-driven design). For theoretical knowledge about DDD, you can refer to other online Data), DDD's strategic design will establish a domain model, which can guide the split of microservices. It is mainly carried out in four steps:
Taking the e-commerce scenario as an example, the boundaries of transaction links are divided The context is shown in the left half of the figure below. A microservice can be designed based on a bounded context. The disassembled microservice is shown on the right side of the figure below.
2. Non-functional dimensions
When we split according to functional dimensions, not everything will be fine. In most scenarios, we need to add other dimensions to further split. Only then can the problems caused by the monolithic architecture be finally solved.
The above splitting methods are not multiple choices, but can be freely arranged and combined according to the actual situation. At the same time, splitting is not only an architectural adjustment, but also means making corresponding adaptive optimizations in the organizational structure to ensure that the split services are maintained by relatively independent teams.
The ancient Greek philosopher Heraclitus once said: "One cannot step into the same river twice." As time goes by, the state of everything will change. The same is true for online systems. Even the status of a system at different times will never be exactly the same. The granularity of the services split out now may be appropriate, but who can guarantee that this granularity will always be correct.
1. Don’t fight an unprepared battle
Whether the development team has enough experience and can control the technology stack of microservices may be the first point to consider. This does not require that the team must have perfect experience to start service splitting. It is best if there are experts in this field in the team. If not, then it may be necessary to conduct sufficient technical demonstrations and rehearsals in advance, at least not to fight an unprepared battle. Avoid dismantling whichever one is simple first. Whichever new business is going to be launched, start one service first. Otherwise, you may encounter some common distributed problems, such as insufficient server resources, difficulty in operation and maintenance, confusing calls between services, call retries, timeout mechanisms, distributed transactions, etc.
2.**Continuous correction**
We need to admit that our knowledge is limited and can only make decisions based on the current business status and limited predictions of the future. A relatively suitable splitting plan, rather than the so-called optimal plan. Any plan can only ensure that it provides a relatively suitable granularity and division principle at the moment. We must always be prepared that it will become inappropriate at the last moment in the future. , need to prepare for adjustment again. Therefore, as the business evolves, we need to re-examine whether the division of services is reasonable. If the division of services is too detailed, resulting in a decrease in personnel efficiency and a greatly increased probability of failure, the domain boundaries need to be re-divided.
3. Be an action person, not a theoretical person
Don’t be too obsessed with whether it is suitable or not when it comes to how to split it. How do you know if it is suitable without taking action? If you find it really doesn't fit after you dismantle it, just readjust it. You might say that realignment costs are relatively high. But in fact, the essence of this problem is whether a complete capability system has been built for service-oriented architecture, such as service governance platform, data migration tools, data double-writing, etc. If so, the cost of readjustment will not be Too high.
Arranged on the train to Dalian on June 11, 2021, arriving at the station ahead: Panjin.