In the microservice architecture, the call chain may be very long, from
rpc, and from
http. Developers want to know the call status and performance of each link, the best solution is full link tracking.
The tracking method is to generate its own
spanID at the beginning of a request, and pass it down along the entire request link. We use this
spanID to view the status of the entire link and performance issues.
Let's take a look at the link implementation of
- spancontext ：保存链路的上下文信息「traceid，spanid，或者是其他想要传递的内容」
- span ：链路中的一个操作，存储时间和某些信息
- propagator ：
- noop ：实现了空的
span, first introduce
context. SpanContext saves the context information of distributed tracing, including Trace id, Span id and other content that needs to be passed downstream. The implementation of OpenTracing needs to pass the SpanContext through a certain protocol to associate the Span in different processes to the same Trace. For HTTP requests, SpanContext is generally passed using HTTP headers.
Below is the
spanContext implemented by
go-zero by default
At the same time, developers can also implement the interface methods provided by
SpanContext to realize their own contextual information transfer:
A REST call or database operation, etc., can be used as a
span is the smallest tracking unit of distributed tracing. A trace is composed of multiple spans. The tracking information includes the following information:
Judging from the definition structure of
span: In microservices, this is a complete sub-calling process, with the start of the call
startTime, the context structure
spanContext that marks its own unique attribute, and the number of child nodes of fork.
- Set header -> carrier to get the traceId and other information in the header
- Open a new span and encapsulate "traceId, spanId" in the context
- Obtain traceId and spanId from the aforementioned carrier "that is, header" -See if it is set in the header -If it is not set, it will be randomly generated and returned
- Generate a new ctx from
request, encapsulate the corresponding information in ctx, and return
- From the above context, copy a copy to the current
In this way, the information of the
span is passed to the downstream service along with the
client, server in rpc, so from
tracing there are also
clientTracing, serverTracing. The logic of
serveTracing is basically the same as that of http. Let’s take a look at how
clientTracing is used?
- Get the span context information brought down by the upstream
- Create a new ctx from the acquired span, span "inherit the traceId of the parent span"
- Add the span generated data to ctx, pass it to the next middleware, and flow downstream
go-zero obtains the link traceID by intercepting the request, and then assigns a root Span at the entry of the middleware function, and then splits the child Spans in subsequent operations. Each span has its own specific identification. After Finsh Will be collected in the link tracking system. Developers can trace the traceID through the ELK tool to see the entire call chain.
At the same time,
go-zero does not provide a complete set of
trace link solutions. Developers can encapsulate the existing
span structure of
go-zero, build their own reporting system, and access links such as
jaeger, zipkin, etc. Tracking tool.