核心组件
可以看出代码中围绕的是
- Tracing
- Tracer
- PendingSpans
- TraceContext
什么是Tracing,Tracing可以看做是构建Tracer的一个构建器,他们是1:1的关系
什么是Tracer,Trace是控制产生Span的接口,用于创建一个Span
什么是Span,Span可以看做是一个阶段, 一个链路由多个阶段组成, 因此一个Span可以有父Span,以及生成子Span
什么是TraceContext, TraceContext可以作为一个Span阶段的参数存储以及远程传输的参数存储,例如SpanId,ParentSpanId 等,
和Span 是 1:1的关系
- 如何开启一个新的追踪阶段, 这是Tracer类的第一个方法,可以看出, 一个Span对应一个父类的Context和当前的Context,父可以为空
Q1. Span和TraceContext放在哪里
Q2. Span如何使用
public Span newTrace() {
return _toSpan(null, newRootContext(0));
}
Span _toSpan(@Nullable TraceContext parent, TraceContext context) {
if (isNoop(context)) return new NoopSpan(context);
// 这一步创建一个Span
PendingSpan pendingSpan = pendingSpans.getOrCreate(parent, context, false);
TraceContext pendingContext = pendingSpan.context();
// A lost race of Tracer.toSpan(context) is the only known situation where "context" won't be
// the same as pendingSpan.context()
if (pendingContext != null) context = pendingContext;
// 【最终返回的是RealSpan】
return new RealSpan(context, pendingSpans, pendingSpan.state(), pendingSpan.clock());
}
A1. Span放在pendingSpans的Map里, Key为Context,Value为Span, 因此 Span和Context是1:1的关系
// 创建Span的逻辑
// 可以看出一个Span (PendingSpan)包含了 一个 context, span, clock
public PendingSpan getOrCreate(
@Nullable TraceContext parent, TraceContext context, boolean start) {
// 【这个是典型的先从缓存拿, 没有就创建, 可以知道】
PendingSpan result = get(context);
if (result != null) return result;
// 【创建 Span】
MutableSpan span