Spring Cloud source code analysis (4) Zuul: core filter

Through the previously published article "Spring Cloud Builds Microservice Architecture (5) Service Gateway" , I believe that everyone has a basic understanding of Spring Cloud Zuul. Through the previous introduction, our first impression of Zuul is usually this: it includes two functions: routing and filtering of requests. The routing function is responsible for forwarding external requests to specific microservice instances, which is to achieve external access. The basis of unified entry; and the filter function is responsible for intervening in the request processing process, which is the basis for realizing functions such as request verification and service aggregation. However, in reality, when the routing function is actually running, its route mapping and request forwarding are done by several different filters. Among them, the route mapping is mainly completed by the pre-type filter, which matches the request path with the configured routing rules to find the target address that needs to be forwarded; and the part of the request forwarding is completed by the route-type filter. The routing address obtained by the pre-type filter is forwarded. Therefore, the filter can be said to be the core component of Zuul's API gateway function. Each HTTP request entering Zuul will go through a series of filter processing chains to get the request response and return it to the client.

 

Next, let's take a closer look at Spring Cloud Zuul's filters through this article! The following content is excerpted from "Spring Cloud Microservices in Practice", with a little processing.

 

filter

Filters implemented in Spring Cloud Zuul must contain 4 basic characteristics: filter type, execution order, execution conditions, and specific operations. These elements look very familiar, but in fact they are the four abstract methods defined in the ZuulFilter interface:

 

1
2
3
4
5
6
7
String filterType() ;
 
int filterOrder() ;
 
boolean shouldFilter() ;
 
Object run() ;

 

Their respective meanings and functions are summarized as follows:

 

  • filterType: This function needs to return a string to represent the type of filter, and this type is defined in each stage of the HTTP request process. Four filter types with different life cycles are defined by default in Zuul, as follows:
    • pre: Can be called before the request is routed.
    • routing: Called when routing requests.
    • post: Called after routing and error filters.
    • error: Called when an error occurs while processing the request.
  • filterOrder: The execution order of the filter is defined by the int value. The smaller the value, the higher the priority.
  • shouldFilter: Returns a boolean type to determine whether the filter is to be executed. We can use this method to specify the valid range of the filter.
  • run: The specific logic of the filter. In this function, we can implement custom filtering logic to determine whether to intercept the current request, not to perform subsequent routing, or to process the processing results after the request routing returns the results.

 

request life cycle

In the previous section, we have made some brief introductions to the filter type filterType in Spring Cloud Zuul. Zuul defines four different filter types by default, which cover an external HTTP request reaching the API gateway until it returns The full lifetime of the request result. The following figure is derived from the diagram of the request life cycle in Zuul's official WIKI, which describes the detailed process of how an HTTP request flows between different types of filters after it reaches the API gateway.

 

Official diagram of the request life cycleOfficial diagram of the request life cycle

 

From the above figure, we can see that when an external HTTP request arrives at the API Gateway service, it will first enter the first stage pre, where it will be processed by the pre-type filter, which is mainly The purpose is to do some preprocessing before request routing, such as request verification. After completing the pre-type filter processing, the request enters the second stage of routing, which is the routing request forwarding stage mentioned earlier. The request will be processed by the routing-type filter. The specific processing content here is to forward the external request to In the process of going up a specific service instance, when the service instance returns the request results, the routing phase is completed, and the request enters the third phase, post, at this time, the request will be processed by post-type filters. When these filters are processed Not only the request information, but also the return information of the service instance can be obtained, so in the post type filter, we can perform some processing or conversion on the processing result. In addition, there is a special stage error, which is only triggered when an exception occurs in the above three stages, but its final flow is still a post type filter, because it needs to return the final result through the post filter. To the requesting client (there are some differences in the actual implementation, which will be introduced later).

 

core filter

In Spring Cloud Zuul, in order to make the API Gateway component more convenient to use, it implements a number of core filters by default in each stage of the HTTP request life cycle, which will be automatically loaded when the API Gateway service starts. and enable. We can view and understand them in the source code, they are defined under the org.springframework.cloud.netflix.zuul.filters package of the spring-cloud-netflix-core module.

 

Core filters implemented by defaultCore filters implemented by default

 

As shown in the figure above, the filters that are enabled by default include three filters with different life cycles. These filters are very important and can help us understand Zuul's process of processing external requests and how to build on this. Extend the filter to perform the functions required by your own system. Below, we'll go into some detail about each of these filters:

 

pre filter

  • ServletDetectionFilter: Its execution order is -3, which is the first filter to be executed. This filter is always executed and is mainly used to detect whether the current request is processed and run through Spring's DispatcherServlet or through ZuulServlet. Its detection result will be saved in the isDispatcherServletRequest parameter of the current request context as a Boolean type, so that in subsequent filters, we can judge it through the RequestUtils.isDispatcherServletRequest() and RequestUtils.isZuulServletRequest() methods to achieve different processing. . Under normal circumstances, external requests sent to the API Gateway will be processed by Spring's DispatcherServlet, except for requests accessed through the /zuul/ path, which will bypass DispatcherServlet and be processed by ZuulServlet, which is mainly used to deal with large file uploads. In addition, for the access path /zuul/ of ZuulServlet , we can modify it through the zuul.servletPath parameter.
  • Servlet30WrapperFilter: Its execution order is -2 and it is the second executed filter. The current implementation takes effect for all requests, mainly to wrap the original HttpServletRequest into a Servlet30RequestWrapper object.
  • FormBodyWrapperFilter: Its execution order is -1 and it is the third executed filter. This filter is only valid for two types of requests. The first type is requests whose Content-Type is application/x-www-form-urlencoded, and the second type is those whose Content-Type is multipart/form-data and processed by Spring's DispatcherServlet The request (using the processing result of the ServletDetectionFilter). The main purpose of this filter is to wrap the request body that meets the requirements into a FormBodyRequestWrapper object.
  • DebugFilter: Its execution order is 1 and it is the fourth executed filter. The filter will decide whether to execute the operation in the filter according to the configuration parameter zuul.debug.request and the debug parameter in the request. Its specific operation content is to set the debugRouting and debugRequest parameters in the current request context to true. Since these two values ​​can be accessed in different life cycles of the same request, we can use these two values ​​to define some debug information in subsequent filters, so that when there is a problem in the online environment, These debug messages can be activated by request parameters to help analyze the problem. In addition, for the debug parameter in the request parameter, we can also customize it through zuul.debug.parameter.
  • PreDecorationFilter: Its execution order is 5, which is the last filter executed in the pre stage. The filter will determine whether the forward.to and serviceId parameters exist in the current request context. If neither exists, then it will perform the operation of the specific filter (if there is one, it means that the current request has been processed, because These two information are loaded according to the routing information of the current request). Its specific operation content is to do some preprocessing for the current request, such as: matching the routing rules, setting the basic information of the request in the request context, and setting the route matching results, etc., which will be used for subsequent filtering. It is an important basis for the processor to process, and we can access this information through RequestContext.getCurrentContext(). In addition, we can also find some logic for processing HTTP header requests in this implementation, including some well-known header fields, such as: X-Forwarded-Host, X-Forwarded-Port. In addition, the records of these header fields are controlled by the zuul.addProxyHeaders parameter, and the default value of this parameter is true, so Zuul will add X-Forwarded-* header fields to the request by default when the request jumps, including: X -Forwarded-Host, X-Forwarded-Port, X-Forwarded-For, X-Forwarded-Prefix, X-Forwarded-Proto. We can also disable the addition of these header fields by setting zuul.addProxyHeaders=false.

 

The operation invocation of loading sensitive header information into ignore header information mentioned in the article "Spring Cloud Practical Tips: Zuul Handling Cookies and Redirection" is implemented in the PreDecorationFilter filter.

 

route filter

  • RibbonRoutingFilter: Its execution order is 10, and it is the first filter executed in the route phase. This filter only processes requests with the serviceId parameter in the request context, that is, it only takes effect on requests for which routing rules are configured through serviceId. The execution logic of the filter is the core of service-oriented routing. It uses Ribbon and Hystrix to initiate a request to the service instance and returns the request result of the service instance.
  • SimpleHostRoutingFilter: Its execution order is 100, and it is the second filter executed in the route phase. This filter only processes requests with the routeHost parameter in the request context, that is, it only takes effect on requests for which routing rules are configured through url. The execution logic of the filter is to directly initiate a request to the physical address of the routeHost parameter. From the source code, we can know that the request is implemented directly through the httpclient package, without using the Hystrix command for packaging, so there is no thread isolation for this type of request. and circuit breaker protection.
  • SendForwardFilter: Its execution order is 500, and it is the third filter executed in the route phase. This filter only processes the request with the forward.to parameter in the request context, that is, it is used to process the forward local jump configuration in the routing rule.

 

post filter

  • SendErrorFilter: Its execution order is 0, and it is the first filter executed in the post stage. This filter is only executed if the request context contains the error.status_code parameter (the error code set by a previously executed filter) and has not been processed by this filter. The specific logic of the filter is to use the error information in the request context to organize a request forwarded to the API gateway/error error endpoint to generate an error response.
  • SendResponseFilter: Its execution order is 1000, which is the last filter executed in the post stage. The filter will check whether the request context contains the request-response-related header information, the response data stream, or the response body, and only execute processing logic if one of them is included. The processing logic of the filter is to use the response information of the request context to organize the response content that needs to be sent back to the client.

 

The specific code is not listed here. The reader can view the source code according to the class name to understand the detailed processing process. The following figure is a comprehensive arrangement of the above filters according to order, name, function and type, which can help us to refer to and comprehensively consider the processing process of the entire request life cycle when customizing or extending filters. .

Core Filter Summary

 

 

 

http://blog.didispace.com/spring-cloud-source-zuul/

http://blog.csdn.net/forezp/article/details/76211680

 

 

 

Guess you like

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