Trace

    In the microservice architecture, the call chain may be very long, from to rpc, and from rpc to 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 go-zero.

    Code structure

    • :保存链路的上下文信息「traceid,spanid,或者是其他想要传递的内容」
    • span :链路中的一个操作,存储时间和某些信息
    • trace 传播下游的操作「抽取,注入」
    • noop :实现了空的 tracer 实现

    Below is the spanContext implemented by 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. 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.

    Example application

    1. Set header -> carrier to get the traceId and other information in the header
    2. 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
    3. Generate a new ctx from request, encapsulate the corresponding information in ctx, and return
    4. From the above context, copy a copy to the current request

    Trace - 图2

    In this way, the information of the span is passed to the downstream service along with the .

    There are 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?

    1. Get the span context information brought down by the upstream
    2. Create a new ctx from the acquired span, span “inherit the traceId of the parent span”
    3. 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.

    Reference