golang 链路追踪

Golang中主要结合jaeger和opentracing去实现链路追踪

链路追踪中的基本概念:

tracer、span

tracer代表了一个流程或事务在分布式系统中的执行过程,tracer由多个span构成的有向无环图,每个span代表tracer中被命名并计时的连续性执行片段

span代表系统中具有开始时间和执行时长的逻辑单元,span之间通过嵌套或者顺序排列建立逻辑因果关系

关系:

分布式追踪中的每个组件都包含自己的一个或者多个span。例如,在一个常规的RPC调用过程中,在RPC的客户端和服务端,至少各有一个span,用于记录RPC调用的客户端和服务端信息。

一个父级的span会显示的并行或者串行启动多个子span。

一个 tracer 过程中,各span的关系

        [Span A]  ←←←(the root span)
            |
     +------+------+
     |             |
 [Span B]      [Span C] ←←←(Span C 是 Span A 的孩子节点, ChildOf)
     |             |
 [Span D]      +---+-------+
               |           |
           [Span E]    [Span F] >>> [Span G] >>> [Span H]
                                       ↑
                                       ↑
                                       ↑
                         (Span G 在 Span F 后被调用, FollowsFrom)

tracer和span的时间轴关系

tracer 与 span 的时间轴关系


––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time

 [Span A···················································]
   [Span B··············································]
      [Span D··········································]
    [Span C········································]
         [Span E·······]        [Span F··] [Span G··] [Span H··]

在分布式服务中需要用一个标志连接彼此的关系

traceId

假设服务调用关系为 a->b->c->d,请求从 a 开始发起。 那么 a 负责生成 traceId,并在调用 b 的时候把 traceId 传递给 b,以此类推,traceId 会从 a 层层传递到 d。

这个 traceId 长这样: {root span id}:{this span id}:{parent span id}:{flag} 。假设 a 是请求发起者,flag 固定为1,那么 a,b,c,d 的 traceId 分别是:

a_span_id:a_span_id:0:1
a_span_id:b_span_id:a_span_id:1
a_span_id:c_span_id:b_span_id:1
a_span_id:d_span_id:c_span_id:1

jaeger的5大组件:

jaeger-client:代码接入的 jaegerClient。

jaeger-agent:jaeger-client 会把 span 上报给 jaeger-agent,这个 aegent 最好和 jaeger-client 部署在同一台服务器,离得近上报也快,否则可能会因为上报数据反而拖累业务

jaeger-collector:负责从 jaeger-agent 那里拿数据的服务, 有 push /pull 两种方式

storage:存储jaeger-collector 拿到的数据的地方,可以选 es 或者 cassandra。

jaeger-query:负责从 storage 查询数据

运行流程图:

一个简单的微服务使用链路追踪实例

posted @ 2022-03-04 19:59  LeeJuly  阅读(1021)  评论(0编辑  收藏  举报