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 查询数据
运行流程图:
一个简单的微服务使用链路追踪实例
本文来自博客园,作者:LeeJuly,转载请注明原文链接:https://www.cnblogs.com/peterleee/p/15965911.html