写点什么

skywalking 核心概念

  • 2022 年 1 月 13 日
  • 本文字数:1980 字

    阅读完需:约 6 分钟

TraceSegment

在 skywalking 中,TraceSegment 是一个介于 Trace 与 Span 之间的概念。它是 Trace 的一段,包含多个 Span。

public class TraceSegment {    /**     * TraceSegment的全局唯一标识,由GlobalIdGenerator生成。     */    private String traceSegmentId;
/** * 指向父 TraceSegment。在常见的RPC调用等跨进程调用中,一个 TraceSegment 最多只有一个父 * TraceSegment。但在一个Consumer批量消费MQ消息时,同一批内的消息可能来自不同的Producer会导致 * Comsumer线程对应的TraceSegment有多个父TraceSegment。新版本中只会保留一个最开始的父 TraceSegment。 */ private TraceSegmentRef ref;
/** * 当前 TraceSegment 包含的所有 Span。 */ private List<AbstractTracingSpan> spans;
/** * 当前 TraceSegment 所属 Trace 的 Trace ID。 */ private DistributedTraceId relatedGlobalTraceId;
/** * ignore字段表示当前TraceSegment是否被忽略,主要是为了忽略一些问题TraceSegment(针对只包含一个Span) * 进行采样收集。 */ private boolean ignore = false;
/** * 容错设计,例如业务代码出现了死循环Bug,可能会向相应的TraceSegment中不断添加Span,为了防止对应用内 * 存以及后端存储造成不必要的压力,每个TraceSegment中Span的个数是有上限的,超过上限后就不再添加Span */ private boolean isSizeLimited = false;
private final long createTime;}
复制代码



在微服务架构中,一个请求基本都会涉及跨进程(以及跨线程)的操作,例如, RPC 调用、通过 MQ 异步执行等,处理一个请求就需要涉及到多个服务的多个线程。TraceSegment 记录了一个请求在一个服务中的执行流程(即 Trace 信息)。将该请求关联的 TraceSegment 串联起来,就能得到该请求对应的完整 Trace。

Span

skywalking 中 span 共有三种类型:

  • EntrySpan

当请求进入服务时会创建 EntrySpan 类型的 Span,它也是 TraceSegment 中的第一个。

  • LocalSpan

是在本地方法调用时可能创建的 Span 类型。

  • ExitSpan

当请求离开当前服务,进入其他服务时会创建 ExitSpan 类型的 Span。

protected int spanId; // Span的IDprotected int parentSpanId; // 记录父Span的IDprotected List<TagValuePair> tags; // 记录Tags的集合protected String operationName; // Span的操作名称,常见的有Rest服务的接口名称protected long startTime; // Span开始时间protected long endTime; // Span结束时间,与开始时间一起计算耗时protected List<TraceSegmentRef> refs; // 指向所属TraceSegmentprotected List<LogDataEntity> logs; // 日志信息,常见的是包含异常堆栈的异常日志protected final TracingContext owner; // owner字段指向TracingContext,TracingContext与当前线程绑定,与TraceSegment一一对应protected List<LogDataEntity> logs; // 日志信息,常见的是包含异常堆栈的异常日志
复制代码

Span 管理


我们来看下 span 的管理,当请求通过 Tomcat 的时候,创建一个 EntrySpan,然后调用 EntrySpan 的start()方法,会把 EntrySpan 放入到 span 队列的 activeSpanStack 中,当请求经过 springMvc 的时候,不会再创建 EntrySpan,只会重新调用 EntrySpan 的start()方法,当在业务方法中调用接口的first()方法的时候,会创建一份 LocalSpan,并且把 LocalSpan 添加到 activeSpanStack 中,当first()方法调用结束的时候,LocalSpan 会出栈,当调用业务的second()方法的时候,会创建一份 LocalSpan,并且把 LocalSpan 添加到 activeSpanStack 中,当second()方法调用结束的时候,LocalSpan 会出栈。接下来使用 Feign 接口远程调用greeting()方法的时候,会创建一个 ExitSpan,然后将 ExitSpan 添加到 activeSpanStack 中,当greeting()方法调用结束的时候,会将 ExitSpan 出栈,最后请求结束,第一个 EntrySpan 出栈。

跨进程传播

ContextCarrier 是 TracingContext 上下文的搬运工,负责在进程之间搬运 TracingContext 的一些基本信息,其中就包括 Trace ID。服务端负责从 ContextCarrier 中提取链路信息,而客户端则通过向 ContextCarrier 注入链路信息从而传输到服务端。

跨线程传播

TracingContext 对跨线程传播的支持涉及capture()方法和continued()。跨线程传播时使用 ContextSnapshot 为 Context 上下文创建快照,在异步线程中通过快照信息还原 TraceSegment 信息。

Skywalking 链路传播框图

我们在一次调用里面,所经历的一个线程,会生成一个 TraceSegment 。这里它经历了 4 个线程,不管是否跨 JVM ,A 里面 1 个,B 里面 1 个,B 里面的 New Thread 1 个,C 里面 1 个,所以它经历了四个线程后就会生成四 TraceSegment 对象。一次调用经过一个线程就会产生一个 TraceSegment,整个 Trace 的调用链就是由多个 TraceSegment 构成的。


发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2021.01.27 加入

还未添加个人简介

评论

发布
暂无评论
skywalking核心概念