Let's first get to know the various components of SpringCloud, and then understand why.
Principle analysis of each component of Spring Cloud architecture
Before explaining the principle, let s look at one of the most classic business scenarios, such as developing an e-commerce website. To realize the function of paying orders, the process is as follows:
- After creating an order, if the user pays the order immediately, we need to update the order status to "paid"
- Deduct the corresponding merchandise inventory
- Notify the warehouse center for delivery
- Add corresponding points to the user for this purchase
As above, the application scenarios and core competitiveness of microservices:
- Reduce coupling: Each microservice focuses on a single function, and clearly expresses the service boundary through a well-defined interface. Due to its small size and low complexity, each microservice can be fully controlled by a small-scale development team, and it is easy to maintain high maintainability and development efficiency.
- Independent deployment: Since microservices have independent running processes, each microservice can also be deployed independently. When a microservice changes, there is no need to compile and deploy the entire application. An application composed of microservices is equivalent to having a series of parallel release processes, making the release more efficient, while reducing the risk to the production environment, and ultimately shortening the application delivery cycle.
- Flexible selection: Under the microservice architecture, technology selection is decentralized. Each team can freely choose the most suitable technology stack according to its own service needs and the status quo of industry development. Since each microservice is relatively simple, the risk of upgrading the technology stack is low, and even a complete restructuring of a microservice is feasible.
- Fault-tolerant mechanism: When a component fails, under the traditional architecture of a single process, the fault is likely to spread within the process, resulting in global unavailability of the application. Under the microservice architecture, faults will be isolated in a single service. If well designed, other services can achieve application-level fault tolerance through mechanisms such as retries and smooth degradation.
- Flexible expansion: Single-block architecture applications can also achieve horizontal expansion, which means that the entire application is completely copied to different nodes. When the different components of the application differ in expansion requirements, the microservice architecture reflects its flexibility, because each service can be expanded independently according to actual needs.
Dubbo benchmarks Spring Cloud microservices:
- Background analysis: Dubbo is the core framework of Alibaba's service-oriented governance and is widely used in various Internet companies in China; Spring Cloud is a product of the well-known Spring family. Alibaba is a commercial company. Although it has also open sourced many top-level projects, it still focuses on serving its own business in terms of overall strategy. Spring focuses on the research and development of enterprise-level open source frameworks, which are widely used in China and in the world. The development of a universal, open source, and robust open source framework is their main business.
- Activity comparison: Dubbo is a very good service governance framework, and it is better than Spring Cloud in terms of service governance, grayscale publishing, and traffic distribution. In addition to the addition of rest support on the basis of Dangdang, Dubbo has There has been almost no update for more than two years. Problems occurred during use, and the Issue submitted to GitHub rarely responded. On the contrary, Spring Cloud has continued to develop at a high speed since its development. It can be seen from the frequency of code submissions on GitHub and the time interval between releases. Now Spring Cloud is about to release version 2.0, which will be more complete and stable in the later period.
- Platform architecture: The Dubbo framework only focuses on the governance between services. If we need to use the configuration center and distributed tracking, we need to integrate it ourselves, which will increase the difficulty of using Dubbo invisibly. Spring Cloud considers almost all aspects of service governance, and with the support of Spring Boot, it is very convenient and simple to develop.
- Technical prospects: Dubbo has also benefited a lot from small and medium-sized companies. After so many years of development, more advanced technologies and concepts have emerged in the Internet industry. Dubbo is a pity. Spring launched Spring Boot/Cloud for many reasons. The lightweight framework advocated by Spring at first became larger and larger with continuous development. With more and more integrated projects, the configuration files became more and more chaotic, gradually deviating from the original concept. With so many years of development and the emergence of more new technical concepts such as microservices and distributed link tracking, Spring urgently needs a framework to improve the previous development model, so the Spring Boot/Cloud project will appear. Let s visit now On the Spring official website, you will find that Spring Boot and Spring Cloud have been placed in the first two of the three most prominent projects on the homepage, which shows how much Spring attaches to these two frameworks. Dubbo is implemented as follows:
Spring Cloud implementation ideas:
Principle: Supervising service registration and discovery, that is, if the name of the microservice is registered with Eureka, the microservice can be found through Eureka without modifying the configuration file of the service call.
Analysis: Spring Cloud encapsulates the Eureka module developed by Netflix to realize service registration and discovery. The design architecture of cs is adopted. Eureka Server serves as the server for the service registration function. It is the service registration center. The other microservices of the system use Eureka's client to connect to the Eureka Server and maintain a heartbeat. In this way, system maintainers can use Eureka Server to monitor whether each microservice in the system is operating normally. Some other modules of Spring Cloud (such as Zuul) can use Eureka Server to discover other microservices of the system and execute related logic.
Eureka Server provides service registration services. After each node is started, it will be registered in Eureka Server. In this way, the service registry in Eureka Server will store the information of all available service nodes. The information of service nodes can be viewed intuitively in the interface. To.
Eureka Client is a Java client used to simplify the interaction of Eureka Server. The client also has a built-in load balancer that uses a round-robin load algorithm. After the application is started, it will send a heartbeat to the Eureka Server (the default period is 30 seconds) to prove that the current service is available. If Eureka Server does not receive the client's heartbeat within a certain period of time (90 seconds by default), Eureka Server will remove the service node from the service registry.
Eureka Server's self-protection mechanism
If more than 85% of the nodes do not have a normal heartbeat within 15 minutes, then Eureka believes that there is a network failure between the client and the registry. At this time, the following situations will occur:
- Eureka no longer removes from the registration list services that should expire because they have not received heartbeats for a long time
- Eureka can still accept new service registration and query requests, but it will not be synchronized to other nodes (that is, to ensure that the current node is still available)
- When the network is stable, the new registration information of the current instance will be synchronized to other nodes
Therefore, Eureka can deal with the situation that some nodes lose contact due to network failures, without paralyzing the entire registration service like ZooKeeper.
Eureka and ZooKeeper
The well-known CAP theory points out that a distributed system cannot satisfy C (consistency), A (availability) and P (partition fault tolerance) at the same time. Since partition fault tolerance must be guaranteed in a distributed system, we can only make a trade-off between A and C.
Search the public account Java Note Shrimp, reply to the "back-end interview", and send you a complete set of interview questions.pdf
ZooKeeper guarantees CP
When querying the registry for the service list, we can tolerate that the registry returns the registration information a few minutes ago, but we cannot accept the service directly down and unavailable. In other words, the service registration function has higher requirements for availability than consistency. But ZooKeeper will have such a situation, when the Master node loses contact with other nodes due to a network failure, the remaining nodes will re-elect the leader.
The problem is that the leader election time is too long, 30 ~ 120s, and the entire ZooKeeper cluster is unavailable during the election, which leads to the paralysis of the registration service during the election. In a cloud deployment environment, it is likely that the ZooKeeper cluster will lose the Master node due to network problems. Although the service can eventually be restored, the long-term unavailability of registration caused by the long election time cannot be tolerated.
Eureka guarantees AP
Eurek prioritizes usability when designing. Each node of Eureka is equal, and the failure of several nodes will not affect the work of normal nodes, and the remaining nodes can still provide registration and query services. When the Eureka client registers with an Eureka or finds that the connection fails, it will automatically switch to other nodes. As long as one Eureka is still there, the registration service can be guaranteed (guaranteed availability), but the information is found May not be up-to-date (strong consistency is not guaranteed).
In addition, Eureka has a self-protection mechanism, see above.
Eureka can deal with the situation that some nodes lose contact due to network failures, without paralyzing the entire registration service like ZooKeeper.
As a pure service registration center, Eureka is more "professional" than ZooKeeper, because the registration service is more important to usability, and we can accept that it cannot achieve consistency in the short term.
Ribbon and Feign
In the microservice architecture, the business is split into an independent service, and the communication between the service and the service is based on HTTP RESTful. Spring Cloud has two service invocation methods, one is Ribbon+RestTemplate, and the other is Feign.
A set of client load balancing tools based on the Netflix Ribbon used polling strategy.
Client load balancing: When a load balancing Zuul gateway sends a request to a certain service application, if a service starts multiple instances, it will be sent to a certain service through a certain load balancing strategy through Ribbon Instance. In Ribbon in Spring Cloud, the client will have a list of server addresses. Before sending the request, select a server through load balancing algorithms (such as simple polling, random connection, etc.), and then access it.
- Load balancing: Used to distribute workloads to multiple servers to improve the performance and reliability of websites, applications, databases, or other services.
- The benefits of using load balancing are obvious: when one or more servers in the cluster are down, the remaining servers that are not down can ensure the continued use of the service; the access pressure is distributed to each server, and it will not be due to a certain The peak time causes the system cpu to rise sharply.
- There are several implementation strategies for load balancing, the common ones are: Random, RoundRobin, ConsistentHash, Hash, Weighted
- Ribbon's default strategy is polling
Traditionally, to access RESTful services in Java code, Apache's HttpClient is generally used, but this method is too cumbersome to use. Spring provides a simple and convenient template class to operate, this is RestTemplate.
Feign is a declarative http client. Using Feign can make it easier to write an http client. Its method of use is to define an interface and then add annotations to it, avoiding the cumbersome need to constantly parse/encapsulate json data when calling the target microservice. In Spring Cloud, Feign integrates Ribbon by default and combines with Eureka to achieve the effect of load balancing by default.
The difference between Ribbon and Feign
Feign goals make it easier to write Java Http clients
When using Ribbon+ RestTemplate, Ribbon needs to construct an http request by itself, simulate the http request and then use the RestTemplate to send it to other services. The steps are quite cumbersome. Using RestTemplate to encapsulate the http request, a template-based calling method is formed. However, in actual development, since there may be more than one service-dependent calls, and an interface is often called in multiple places, some client classes are usually encapsulated for each microservice to package these dependent service calls. Therefore, Feign has further encapsulated on this basis, and he will help us define and implement the definition of the dependent service interface.
Under the implementation of Feign, we only need to create an interface and use annotations to configure it (previously the Dao interface was marked with Mapper annotations, now it is a microservice interface marked with a Feign annotation), and the service can be completed The provider's interface binding simplifies the amount of development that automatically encapsulates the service call client when using Spring Cloud Ribbon.
Search the public account Java Note Shrimp, reply to the "back-end interview", and send you a complete set of interview questions.pdf
Feign integrates Ribbon
Ribbon implements client load balancing through polling. Unlike Ribbon, Feign is a declarative web service client, which makes it very easy to write a web service client. You only need to create an interface and add it to it. Note, you can call it just like calling a local method, and you don't feel like calling a remote method. In SpringCloud, Feign integrates Ribbon by default and combines with Eureka to achieve the effect of load balancing by default.
The difference between Ribbon and Nginx
Server-side load balancing Nginx
Nginx is that all client requests are handed over to Nginx, and Nginx performs load balancing request forwarding, which belongs to server-side load balancing. Both requests are forwarded by the Nginx server. Client load balancing Ribbon, Ribbon obtains a list of service registration information from the server side of the Eureka registry, caches it locally, and then implements a polling load balancing strategy locally. Both achieve load balancing on the client side.
The difference in application scenarios
Nginx is suitable for server-side load balancing. For example, Tomcat and Ribbon are suitable for RPC remote calls in microservices to achieve local service load balancing. For example, Dubbo and Spring Cloud all use local load balancing.
If there are currently more than a dozen microservices, orders, products, users, etc., it is obvious that the client does not need to deal with each service one by one. This requires a unified entrance, which is the service gateway. All clients of the API gateway request access to the back-end services through this gateway. He can use certain routing configuration to determine which service handles a certain URL. And get the registered service from Eureka to forward the request.
Zuul contains the two most important functions of request routing and filtering. It is a unified entry for various services and is also used to provide monitoring, authorization, security, scheduling, and so on.
Routing function: Responsible for forwarding external requests to specific microservice instances, which is the basis for realizing a unified entry for external access.
Filter function: It is responsible for intervening in the processing of requests, which is the basis for realizing functions such as request verification and service aggregation.
Zuul and Eureka are integrated: Zuul itself is registered as an application under Eureka service governance, and messages from other microservices are obtained from Eureka, that is, future access to microservices is obtained after Zuul jumps.
Note: Zuul service will eventually be registered into Eureka, providing three functions: proxy + routing + filtering.
The core of Zuul is a series of filters, whose function can be analogous to the Filter of the Servlet framework, or AOP.
There is no direct communication between filters, but data transfer through Request Context.
Zuul filters are written by Groovy. These filter files are placed under specific directories on Zuul Server. Zuul will poll these directories regularly, and the modified filters will be dynamically loaded into Zuul Server for use in filtering requests.
Zuul load balancing: Zuul intercepts the corresponding API prefix request and forwards it to the corresponding serverId. On the Eureka service, the same serverId can correspond to multiple services, which means that two instances of the same service node are registered with different ports. But the serverId is the same as Zuul when doing forwarding, it will combine with eureka-server to achieve a load balancing effect.
Types of filters:
- PRE: This filter is called before the request is routed. We can use this filter to realize authentication, current limiting, parameter verification and adjustment, etc.
- ROUTING: This filter routes requests to microservices. This filter is used to construct requests sent to microservices and use Apache HttpClient or Netfilx Ribbon to request microservices.
- POST (Post): This filter is executed after routing to the microservice. This filter can be used to add a standard HTTP header to the response, collect statistics and metrics, send the response from the microservice to the client, log, etc.
- ERROR: execute this filter when errors occur in other stages.
Zuul and Nginx
Although Zuul is incomparable to Nginx in performance, it also has its advantages. Zuul provides edge services such as authentication and authorization, dynamic routing, monitoring, resiliency, security, load balancing, etc. When the team is small and not specifically responsible for routing development, using Zuul as a gateway is a good solution to get started quickly.
Nginx and Zuul can be used together to give full play to their respective advantages. Nginx is used as a load balancer to achieve high concurrent request forwarding, and Zuul is used as a gateway.
Zuul and Ribbon achieve load balancing
Zuul supports Ribbon and Hystrix, and can also achieve client load balancing. Doesn't our Feign also implement client-side load balancing and Hystrix? Now that Zuul can be realized, is our Feign still necessary?
It can be understood like this:
Zuul is the only interface exposed to the outside, which is equivalent to routing the request of the controller, while Ribbonhe and Fegin route the request of the service.
Zuul does the load balancing of the outermost requests, while Ribbon and Fegin do the load balancing of the service calls of various microservices in the system.
Hystrix is an open source library used to deal with the delay and fault tolerance of distributed systems. In distributed systems, many dependencies that cannot be avoided will fail to call, such as timeouts, exceptions, etc. Hystrix can guarantee that in the case of a dependency problem, Will not cause overall service failure, avoid cascading failures, and improve the resilience of distributed systems. Hystrix appeared to solve the avalanche effect.
When calling between multiple microservices, suppose that microservice A calls microservice B and microservice C, and microservice B and microservice C call other microservices. This is the so-called "fan-out". If the call response time of a microservice on the fan-out link is too long or unavailable, the call to microservice A will occupy more and more system resources, which will cause the system to crash, the so-called "avalanche effect."
The fuse mechanism is a microservice link protection mechanism to deal with the avalanche effect.
When a microservice of the deleted link is unavailable or the response time is too long, the service will be degraded, and the call of the microservice of the node will be fuse, and the wrong response message will be returned quickly. When the response of the microservice call of the node is detected The call link is restored after normal. In the SpringCloud framework, the fuse mechanism is implemented by Hystrix. Hystrix will monitor the status of calls between microservices. When the failed calls reach a certain threshold, the default is that 20 calls fail within 5 seconds will start the fuse mechanism The annotation of the fuse mechanism is @HystrixCommand.
The overall resources are almost running out, so I reluctantly turn off some services first, and then turn them back on after getting over the difficulties.
Hystrix monitoring and circuit breaker
We only need to add the Hystrix label to the service interface to realize the monitoring and circuit breaker functions of this interface.
The Hystrix Dashboard monitoring panel provides an interface to monitor the time consumed by service calls on each service.
Hystrix Turbine monitoring aggregation
To use Hystrix monitoring, we need to open the monitoring information of each service instance to view. Turbine can help us aggregate the monitoring information of all service instances into one place for unified viewing. In this way, there is no need to open the pages one by one to view them one by one.
Zuul's security mechanism
Signature mechanism, in order to prevent interface data tampering and repeated calls, an interface parameter verification mechanism is added. The sig signature algorithm is MD5 (appKey+appSecret+timestamp), appKey is the ID assigned to the client, appSecret is the secret key assigned to the client, timestamp It is a Unix timestamp, and the valid time of the requested URL is 15 minutes.
Token mechanism, the user will return an access_ token after logging in, and the client needs to use the Bearer mode to add a new token in the Authorization header when accessing resources that need to be logged in, such as head("Authorization"," Bearer token") .
Hystrix's design principles
- Resource isolation (thread pool isolation and semaphore isolation) mechanism: Limit the use of resources for invoking distributed services, and the problem of a certain invoked service will not affect other service invocations.
- Current limiting mechanism: The current limiting mechanism is mainly to set the highest QPS threshold for each type of request in advance, and if it is higher than the set threshold, the request will be returned directly without calling subsequent resources.
- Fuse mechanism: When the failure rate reaches the threshold, the downgrade is automatically triggered (for example, the failure rate caused by network failure or timeout is really high), and the fast failure triggered by the fuse will recover quickly.
- Degradation mechanism: Degrade over time, degrade when resources are insufficient (threads or semaphores), degrade abnormally, etc. After degrading, you can cooperate with the degraded interface to return backing data.
- Cache support: Provides request cache and request merge implementation.
- Through near real-time statistics/monitoring/alarm functions, the speed of fault discovery can be improved.
- Improve the speed of fault handling and recovery through the near real-time attribute and configuration hot modification function.
Spring Cloud Config is a configuration management solution for distributed systems. Microservices means to split the business in a single application into sub-services. The granularity of each service is relatively small, so a large number of services will appear in the system. Since each service requires necessary configuration information to run, a centralized and dynamic configuration management facility is essential. Spring Cloud provides ConfigServer to solve this problem. Each of our microservices brings an application.yml to manage hundreds of configuration files.
- Inconvenient to maintain, multiple people modify the configuration file at the same time, conflicts continue, and it is difficult to maintain
- Configuration content security and permissions, mainly for online configuration, generally not open to development, only operation and maintenance have permissions, so the configuration file needs to be isolated and not placed in the project code
- Updating the configuration items requires a restart, and each time the configuration file is updated, the items need to be restarted, which is time-consuming. After using the configuration center, the configuration can be updated in real time, congfig Server and Config Client combined with Spring Cloud Bus to achieve automatic configuration refresh.
- The configuration file is stored in the remote Git (such as GitHub, Gitee, etc. repositories). The config-server pulls the configuration file from the remote Git and saves it to the local Git.
- The interaction between the local Git and the config-server is two-way, because when the remote Git cannot be accessed, the configuration file will be obtained from the local Git.
- config-client (ie each microservice) pulls configuration files from config-server.
- Config Server: Provides storage of configuration files and provides the content of configuration files in the form of interfaces.
- Config Client: Obtain data through the interface and initialize its own application based on this data.
Summarized as follows:
Principle analysis of each component of Spring Cloud architecture