Disrupting the perception of microservices: 7 mainstream ideas for deep thinking about microservices

Original address: Liang Guizhao's blog

Blog address: http://blog.720ui.com

Welcome to the official account: "Server Thinking". A group of people with the same frequency, grow together, improve together, and break the limitations of cognition.

1. Escape from monolithic systems and embrace microservices?

The difference between a monolithic system and a microservice is that a monolithic system is a large and comprehensive set of functions, and each server runs the complete service of the application. Microservices are independent and autonomous functional modules, which are part of the ecosystem and have a symbiotic relationship with other microservices. Now, the industry's general view on monolithic systems and microservices is that monolithic systems are very easy to develop, test, and deploy, but there are also many problems faced by monolithic systems, such as lower development efficiency, increased maintenance costs, and changes in deployment impact. Large size, poor scalability, and high technology selection costs, and the introduction of microservices can make each microservice easy to develop and maintain, facilitate communication and collaboration, and is very suitable for agile development and continuous delivery of small teams; the responsibility of each microservice Single, high cohesion, low coupling. At the same time, each microservice can be developed, run independently, and deployed independently; each microservice is independent. If a service is deployed or down, it will only affect the current service, not the entire business system. Influence; each microservice can independently expand horizontally and vertically in the face of massive users and high concurrency as the scale of the system continues to expand; each microservice can use different programming languages ​​and different storage technologies, making us more Easy to try new techniques. In addition, the business restructuring of a single service will not face a large business burden and technical bonds.

The author's point of view on the microservice system is that in the process of transforming from a monolithic system to a microservice system, we need to think carefully about which stage to use microservices. Microservices are not a silver bullet. They put forward higher requirements for the difficulty of design and operation and maintenance, and also bring some technical complexity. Therefore, we need to think about and solve solutions such as distributed complexity, data consistency, service management and operation and maintenance, and automatic deployment of services. In fact, microservices reduce the complexity of a single service by splitting a monolithic system into multiple smaller services. However, we look at it as a whole. This approach has resulted in the existence of a large number of services, and the services The mutual calls between them will also increase, resulting in a more complex system architecture.

We often ignore business value and cost considerations, and pursue technology too much, which may lead to our well-designed distributed architecture seriously affecting the speed of our development and the rapid iteration of our business, and with business uncertainty often lead to our The structure is not fully applicable within half a year to a year, and it needs to be rebuilt. In addition, if the business does not develop, it will also lead to the blind waste of a lot of server resources in the early stage, which is not worth the gain for the start-up business. Therefore, in the early stage of the project, in order to ensure rapid business growth, ensure that the system is as independent and complete as possible, and reduce the technical complexity after the introduction of the microservice architecture. For example, it puts forward higher requirements for the difficulty of operation and maintenance, because good microservices Architecture requires stable infrastructure. As the business develops well, the scale of the system will continue to expand, and its scalability, scalability, availability, and performance limit our business development. Service transformation.

The microservice architecture uses services as modular units. Then, we can initially isolate dependencies through Maven's module modularization in the early design, and reserve space for our subsequent transformation. Note that microservices are symbiotic relationships in the ecosystem. Here, it is not only limited that they may have link dependencies, but their business value must be symbiotic. Therefore, in the later stage, the core value and key functions of the single system are identified, and then these functions are divided into independent and self-complete modules. Here, the transformation plan can be read in the author's "Highly Available and Scalable Microservice Architecture: Based on Dubbo, Spring Cloud and Service Mesh" Chapter 12 "Microservice Architecture Transformation of Legacy Systems".

To sum up, microservices reduce the complexity of a single service by splitting a monolithic system into multiple smaller services. However, from an overall perspective, this approach has resulted in the existence of a large number of services, and the services The mutual calls between them will also increase, resulting in a more complex system architecture. Therefore, we not only focus on technology, but also need to consider the input-output ratio to maximize the benefits at the current stage.

2. Get rid of the single system and stay away from the big ball of mud?

The monolithic system that many people criticize is that its services are cohesive and confusing, and it looks like a big ball of mud. So, after the service, has this problem been solved? In fact, microservices reduce the complexity of a single service by splitting a monolithic system into multiple smaller services, making a single system appear more functionally clear, but the overall system architecture becomes more complex. In fact, calls between multiple services in a production environment may be the scenario shown in the figure.

Usually, the microservice ecology of the production environment is much more complicated than the above case, and there may be dozens to hundreds of services. Then, for us, how to systematically sort out the dependencies and link relationships between services is very important. Especially in the time of big promotion, it is necessary to provide strong guarantee for the core link, and this work becomes even more important. In this regard, I recommend implementing automatic link grooming through APM's traffic collection.

In addition, we are designing the architecture. Whenever there is a problem of dividing the service granularity, such as the creation of a new project, or when the service boundary is ambiguous, we need to discuss the service boundary clearly and keep our services as cohesive as possible. sex.

3. Can migrating microservices improve system robustness?

Here, there is another mainstream view: a monolithic system is a large and complete set of functions. If a service fails, it will affect the entire business system. However, using microservices can realize that if a service is deployed or shut down It will only affect the current service, not the entire business system.

In fact, this view seems very correct, but in real business scenarios, it is not the key reason driving our transformation. First of all, in order to avoid a single point of failure, a single unit definitely needs clustering and load balancing. It should be noted that clustering, load balancing and microservices (vertical splitting of services) are not mutually exclusive, but in high concurrency and distribution. coexistence relationship. In addition, in order to solve the service deployment, we can consider rolling releases to achieve non-disruption of services. So, a monolithic system is not necessarily unrobust. At the same time, after the introduction of microservices, from the overall point of view, this method has resulted in the existence of a large number of services, and the mutual calls between services will also increase, which will lead to the overall system architecture becoming more complex. The probability of a node failure increases greatly, and more dependencies mean more problems. At this time, assuming that a microservice on one of the call links is down and cannot provide services, how to ensure its own availability for the upstream services that are strongly dependent on it? (I specifically refer to strong dependency calls here, service degradation or circuit breaker mechanisms may damage the business, and are not an effective solution.) Therefore, in many scenarios, the downtime of a certain service may also affect the entire business system.

Therefore, if we do not design for failure and build a system of service governance, it will lead to the unrobustness of the overall service.

4. Can migrating microservices improve system performance?

So, what are the main motivations for migrating microservices? I think the main benefit driver is the scalability of the service and the consideration of improving performance. A service may reach a bottleneck due to the limitation of the host machine. In order to further squeeze the resources of the machine, it is a good idea to split the service. At the same time, we can further realize automatic scaling to adjust the usage of the machine. However, does migrating microservices necessarily improve the performance of the system? My opinion is not necessarily. After serviceization, the call link becomes longer, the original RPC communication may become several times, and the performance loss increases. For example, one of the main challenges of remote multi-activity is network latency. There must be latency problems across cities. Assuming that the cross-region network latency may be within 100 milliseconds, one HTTP request involves one or two hundred cross-city RPC calls. , then the overall response time will increase a lot, so the challenge of delay is very big. Then, in order to solve the problem of data delay, Alibaba first proposed a unitized solution, that is, to make requests converge in the same area to complete, the unit is highly cohesive, and no cross-area access is performed, that is, "unit closure". In addition, there is also the problem of network timeout of cross-service calls, and the hidden danger of synchronization blocking is also increased by retrying.

Therefore, servitization sacrifices the calling performance on the link between services to improve the performance of the entire business system by squeezing machine resources as a whole.

5. Availability of microservices = Is every call provided by the service reliable and available?

The understanding of many people about the availability of microservices is that every call provided by the service is reliable and available. This view is not right. In fact, microservices guarantee the overall availability of their services. Under normal circumstances, if service A calls service B, if the call takes 10 seconds, then the latter situation may block, indirectly, causing the thread pool to burst and the service to be unavailable. Therefore, we will adopt a timeout mechanism to ensure that the result response is completed in a very short time, and there will be no synchronization blocking problem as much as possible.

In addition, if service B fails, all call-dependent services will be blocked. If there are a large number of requests, thread resources will be consumed and the service will be paralyzed. In fact, dependencies between services can lead to cascading propagation, which indirectly leads to an "avalanche" effect of service failure, making the entire microservice system unavailable. To solve this problem, the circuit breaker mechanism comes into play.

6. Are databases in microservices independent and transparent?

A mainstream view of microservices is that each service has its own cache and database, and the cache and database are independent and transparent. Therefore, it is wrong to share cache and share database. What if service A needs to get the data of service B? The general practice is that service B provides an API interface for obtaining the data, and service A performs business assembly by calling this interface. Therefore, after microserviceization, data exchange between services is carried out through interfaces. If service A accesses the data of service B across the business logic of service B, it will destroy the data independence between microservices .

At this point, I need to pour some cold water. There are no absolutes, and there are several special scenarios that may require sharing data. The first is the scenario where the old service transitions to the new service, and the new service reuses the database of the old service to meet the requirements of function and data transition. Second, multiple services may depend on the same data source, such as data aggregation for reports. In this case, if we simply rely on RPC interface calls, it is likely to cause occasional call timeouts, resulting in a greater chance of failures. Then, the common way to solve this problem is to share data, either to synchronize data through data redundancy, and then to aggregate data within the boundary based on local services; Then pass the processed data externally. Third, the more realistic cost issue. In fact, more databases will bring more capital costs. In many cases, we will also consider the problem from the cost of funds. We choose to reuse the original database tables, wait for the business value to be clear, and then consider a separate independent database.

At the same time, shared data technology solutions can avoid costly and repetitive data migrations where the context between data is ambiguous, and can make it easier to adjust the service granularity when needed, and then migrate the data after the service granularity is stable. Therefore, we need to find the right balance between the two, adhere to the mainstream view of microservices as much as possible, and take full advantage of the benefits of microservices.

7. Does the organization guarantee the implementation of microservices?

Microservices put forward new requirements for the organizational structure. It recommends that the large team be split into multiple small teams, and each team operates, develops and operates one or more services, and requires continuous delivery and continuous process flow. Deployment, DevOps.

Different services may be developed and maintained by different teams. In actual scenarios, the convenience of microservices lies more in the fact that a closed loop can be generated within the team. External teams have great communication and collaboration costs. As shown in the figure, Team A's understanding of Service C is a black box. We don't know whether it is a monolithic service or a microservice. It deploys several servers, which downstream services it needs to rely on, and whether there are current limiting, fuse and degradation. strategy, and how to access. If we need to confirm these issues, it usually requires human collaboration and confirmation.

Of course, this is an inevitable problem brought about by organizational division of labor, so we try our best to ensure the cohesion of services within our own team, and divide them around business modules to ensure that microservices have business independence and integrity. There are few service dependencies and chain calls. Here, a new problem is thrown. How "micro" are microservices? In fact, the splitting of services is not as small as possible, and even an extreme case is to split a piece of functionality into a service, which is wrong. Therefore, the splitting granularity should ensure that microservices have business independence and integrity, and the splitting of services is based on business modules. If the business value/technical value of separate services is not clear, then it is enough to have it coupled in this single system throughout the life cycle of the project. With the development and needs of the business, we can adjust the module structure at the source code level of the system and split it into independent microservices.

Sometimes, the team has absolute ownership of the project, so the microservice in production is a "semi-finished product" because of the consideration of the team's interests. The author believes that this situation is not an exception, but the vast majority of the norm. Now, let's look at a case. Team A has developed an "interaction component" that includes a "comment module" function considering the reusability of functions. At this point, Team B developed a similar "interaction component" without their knowledge. Team C also has this requirement. It knows that Team A has this "interactive component" and hopes to reuse it. However, since this "interactive component" is designed with more consideration to Team A's current business, there is no good solution. For example, it does not support the "comment building" function, and because Team A cannot provide support immediately due to the progress of other projects, Team C decides to spend a week after evaluation to develop an "interactive component" that meets its own business needs. . At this point, each project team maintains an "interactive component". In this case, due to the responsibilities and boundaries between teams, there are limitations in the reuse of services, and even a situation of fighting each other. This situation generally requires planning and coordination at the company level. Coincidentally, both team A and team B are working on the work order system, but the two need to be integrated. In order to ensure the existing interests of the two teams, they did not break the original structure for integration, but determined the domain boundary on the original basis. .

In addition, assuming that an external RPC interface is not stable, the general approach is to analyze the cause of instability, but in the case of cross-team cooperation, the external service may be a black box, and the team may be an invisible wall. Then the cost of communication and cooperation is very large. At this time, someone needs to take the lead in the whole link so that everyone's interests can be agreed. Then, the most efficient way at the moment may be to avoid this problem through other means within the team, such as redundant cache or interface adaptation. Therefore, it may be the best solution to maximize business value under the current organizational structure and environment. We need to adapt to the present and look forward to the future. When it comes to interface adaptation, there is actually a very common microservice architecture design: the adapter service mode. Usually, the format of the message body given to us by external services is inconsistent with what we need. At this time, it seems unrealistic for us to promote their transformation. Then, in order to ensure that our business logic does not introduce a large amount of business adaptation logic, we An adaptation layer (adapter service) will be introduced, which adapts the message body of external services into a unified standard format, and then exposes services upward, such as refund adaptation, logistics adaptation, etc.

Therefore, the organization of the company largely influences the determination of service boundaries. Usually, we divide the field within the boundaries of our own team to meet business needs as much as possible. Although this is a "semi-finished product" from a technical point of view, it may be the best way to maximize business value in the current environment. plan. The so-called long-term integration, when everyone sees that it has enough value, it is also a good idea to consider further integration.

Written in the last voice

Finally, let's talk about introducing new technologies to bring technical dividends to the project. A new technology needs to consider learning cost and maintenance cost, as well as availability guarantee and operability. For example, under the escort of the company's operation and maintenance, I can easily use various technologies, etc. However, I may not dare to use MongoDB in another company, because I know that I am not an operation and maintenance expert in this field. There is a problem, and I may not be able to solve it. Then, the introduction of a new technology may have technical risks. Many times we design based on failure, which is precisely the gap between junior engineers and senior engineers. For example, Redis implements distributed locks. Many people only want to see how to implement this logic through code. However, if the master service in the Redis cluster hangs, switch directly to the slave service, because the master-slave asynchronous synchronization, and the distributed lock What is important is that the latest lock data only works, that is, it only works in an instant. At this time, if the distributed lock data is lost, your business will cause repeated requests. If the distributed lock is applied in the business, it must be It is a very important scenario, especially in finance and payment, so the single-point version of Redis distributed lock is not a good method and cannot be used. If you want to use it, you have to solve the stability problem. (Quoting the case shared by the author "Cheng Chao" of "Highly Available and Scalable Microservice Architecture: Based on Dubbo, Spring Cloud and Service Mesh" in the group, which is particularly exciting.) Here, a small digression, back to the topic, we It will often be found that new projects try new technologies, while older projects are more conservative because the former is less costly to trial and error. Interestingly, new companies are more sensitive to the development of technology. For example, many small companies have many practices and implementations in cloud native. At this point, you probably understand the point of view I expressed: usually, behind the use of technology stacks is the company's operation and maintenance assurance, as well as the ability to control the depth of technology. Therefore, we need to reserve new technologies in advance to prepare for the battlefield at any time, but in most cases, we must ensure that we use existing technologies (tools) to maximize business value.

To sum up, this article has precipitated a lot of what I have seen and heard and practical thinking since my work. The core point of view is not to criticize micro-services, but to keep everyone thinking independently, think about architecture from the perspective of pure technology, and look at micro-services. Services, to ensure the use of existing technology (tools) to maximize business value.

write at the end

[Server-side thinking]: Let's talk about the core technology of the server side, and discuss the project structure and practical experience of the first-line Internet. Let all the R&D personnel working alone find their own circle to communicate and discuss together. Here, we can upgrade our cognition, connect with the top technology giants, connect with excellent ways of thinking, connect with the shortest path to solve problems, connect with all excellent methods, and break the limitations of cognition.

More exciting articles, all in "Server Thinking"!

{{o.name}}
{{m.name}}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324093632&siteId=291194637