preface

The previous article shared the model design of the call chain and its sequence diagram. I believe that we have an overall understanding of the call chain through the last article, such as: what is the call chain, what can do and the overall implementation strategy.

In this article we continue with the collection of server-side information and context-passing between services for the invocation chain.

Collect server information

The overall process of server information collection is shown in the figure below. Requests are hijacked before and after application logic is executed by embedding pointcuts in the startup process of application containers (tomcat, etc.).

L Before the execution of the application logic: parse the call chain information in the request and initialize the call chain context;

L After the execution of the application logic: parse the call chain information in response, and output all the call chain information processed in this request to the log file.

Point of tangency implanted

Before introducing pointcuts, we should have an overview of how the Servlet container (tomcat as an example in this article) processes a request.

Images from the Internet

After the Connector receives a connection and converts it into a Request, the Request is passed to the Engine’s Pipeline’s ValveA. Requests in Engine pipes are passed to the Engine Valve Valve. The request is then passed from Engine Valve to a Host pipe, where it is passed to the Host Valve. It then passes from the Host Valve to a pipe of the Context, and from that pipe to the Context Valve. The request is then passed to the Wrapper Valve contained in the Wrapper PIPE inside Wrapper C, where it passes through a Filter Chain and eventually to a Servlet. With the help of Tomcat’s architectural design, we can augment Tomcat’s external capabilities by embedding our own logic into the lifecycle of tomcat processing a request, namely, middleware enhancement technology for UAVs.

Middleware enhancement technology in addition to clever use of tomcat container architecture design but also with the help of Java Instrumentation (it provides us with a dynamic ability to modify bytecode when the object is loaded for the first time, due to the length of this is not explained in detail, do not understand the partner to consult information). Provide a variety of point-of-cut capabilities externally in the UAV through the UAVServer.

With middleware enhancements, there are cut points before and after the application logic is executed, and it is then time to execute our own call chain logic at these cut points.

Use of middleware enhancement techniques in the call chain

The inter-component enhancement technique described above is a framework for dynamically embedding pointcut code into Tomcat code using JavaAgent and providing external capabilities in the form of UAVServer (more on these capabilities in a future article). The light call chain implementation uses the GlobalFilterHandler capability provided by UAVServer.

GlobalFilterHandler: The GlobalFilterHandler here is a middleware enhancement capability that has nothing to do with traditional filters. It provides four capabilities externally:

DoRequest: hijacking the request before all applications process it;

DoResponse: hijacking after all applications process the request;

BlockHandlerChain: block all handlers from the current handler, which is registered in the current handler.

4. BlockFilterChain blocks all filters from the current Filter.

The invocation chain relies on the first two capabilities provided by GlobalFilterHandler to enable the invocation chain logic to be executed before and after the application processes the request.

Light call chain implementation

The specific UML diagram is as follows:

It can be clearly seen from the UML diagram that InvokechainCatalyst (call chain implementation logical entry and call chain required resource initialization implementation class) has carried out secondary enhancement of middleware enhancement technology. It allows consumers to register different handlers in it and dynamically weave into the Adapter before and after the Handler’s preCap and doCap (cut-point terms for before and after logic execution in middleware enhancement techniques) methods, enabling more custom adaptation and personalization logic to be performed. All Catalyst and Adapter use reflection call mode, minimize the dependency of middleware enhancement technology.

With the secondary enhancement technique, we can begin the following call chain drawing.

Light invocation chain map implementation rely mainly on registered on InvokeChainSupporter ServiceSpanInvokeChainHandler. The main drawing process is as follows:

1. Parse the request information, extract the information concerned by the call chain, and put the parsed information into the context;

2, through the parsed request header information for logical diversion, according to different protocol types of different logic processing;

L mq logic

L HTTP logic

L dubbo logic

Initialize the call chain context and the main span context;

4. After the application processes the request, the chain information will be called for unified output.

Now let’s look at what we did in each step.

Parsing request information

For middleware containers such as Tomcat, all requests into Tomcat are wrapped into HttpServletRequest and HttpServletResponse (request and Response) and end up in the user’s servlet. Call chain with the help of middleware enhancement technology will intercept request and response before user logic processing, and resolve whether there is call chain information. If so, encapsulate the call chain information into the context.

Logic shunt

Because the drawing logic of call chains corresponding to different protocols is different, the call chain is distributed once based on the protocol type.

Initialize the invocation chain context

Parses the information in the context of the call chain:

1. If there is no parent node, the current node is regarded as the initialization node and the main span that records the call chain information within the current service is initialized;

2. If there is a parent node, initialize the current node according to the parent node information, and initialize the main span that records the call chain information within the current service.

Main Span: There may be multiple client or inter-service communications within a service, and a main span is required to record information about the last node in the invocation chain within the current service.

Call chain information output

At the end of the user logic processing, the call chain logger retrieves the call chain information for the current service from the context and prints it to the specified log path.

Context passing between services

For different protocol call chains, there are slightly different ways to transmit information, and the specific implementation method uses another capability provided by middleware enhancement technology: AppFrkHook (hook for short, this function will be introduced in detail when the client call chain is implemented). It can hijack the client technology used by the user, such as the user uses httpClient for communication, then hijack the HttpClient and dynamically weave into the code, so as to achieve the effect of injecting call chain context information in the process of HTTP communication. When the target service parses the request information, it invokes the chain context for parsing. When initializing the call chain context logic, use the information passed to initialize the call chain context of the target service, and realize the call chain connection during the cross-system call.

conclusion

By the end of this article, the reader should have a general understanding of the implementation of the middleware enhancement technology and some sense of the GlobalFilterHandler capabilities it provides. We should understand the whole process of drawing the call chain between the server and the service.


Source: Creditease Technology Institute Li Chong