9. Span 生命周期
您可以通过以下方式对 Span 执行以下操作:brave.Tracer
-
start:启动 span 时,将分配其名称并记录开始时间戳。
-
close:span 完成(记录 span 的结束时间),如果 span 被采样,则它有资格进行收集(例如,到 Zipkin)。
-
continue:创建 span 的新实例。 它是它继续的那个的副本。
-
detach:span 不会停止或关闭。 它只会从当前线程中删除。
-
create with explicit parent(使用显式父级创建):您可以创建一个新的 span 并为其设置显式父级。
Spring Cloud Sleuth 为您创建一个实例。为了使用它,您可以自动装配它。Tracer |
9.1. 创建和完成 span
您可以使用 手动创建 Span,如以下示例所示:Tracer
// Start a span. If there was a span present in this thread it will become
// the `newSpan`'s parent.
Span newSpan = this.tracer.nextSpan().name("calculateTax");
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(newSpan.start())) {
// ...
// You can tag a span
newSpan.tag("taxValue", taxValue);
// ...
// You can log an event on a span
newSpan.annotate("taxCalculated");
}
finally {
// Once done remember to finish the span. This will allow collecting
// the span to send it to Zipkin
newSpan.finish();
}
在前面的示例中,我们可以看到如何创建 span 的新实例。 如果此线程中已有 span,则它将成为新 span 的父级。
创建 Span 后始终保持干净。此外,请始终完成要发送到 Zipkin 的任何 span。 |
如果您的 span 包含大于 50 个字符的名称,则该名称将被截断为 50 个字符。 你的名字必须明确而具体。大牌会导致延迟问题,有时甚至会导致异常。 |
9.2. 连续跨度
有时,您不想创建新的 span,但想要继续创建一个新的 span。此类 情况可能如下所示:
-
AOP:如果在到达 aspect 之前已经创建了一个 span,则您可能不想创建新的 span。
-
Hystrix:执行 Hystrix 命令很可能是当前处理的逻辑部分。 实际上,它只是一个技术实现细节,您不一定希望将其作为一个单独的存在反映在 tracing 中。
要继续 span,您可以使用 ,如以下示例所示:brave.Tracer
// let's assume that we're in a thread Y and we've received
// the `initialSpan` from thread X
Span continuedSpan = this.tracer.toSpan(newSpan.context());
try {
// ...
// You can tag a span
continuedSpan.tag("taxValue", taxValue);
// ...
// You can log an event on a span
continuedSpan.annotate("taxCalculated");
}
finally {
// Once done remember to flush the span. That means that
// it will get reported but the span itself is not yet finished
continuedSpan.flush();
}
9.3. 创建具有显式 Parent 的 Span
您可能希望启动一个新的 span 并提供该 span 的显式父级。
假设 span 的父级位于一个线程中,并且您希望在另一个线程中启动新的 span。
在 Brave 中,每当您调用 时,它都会创建一个引用当前范围内的 span 的 span。
您可以将 span 放入 scope,然后调用 ,如以下示例所示:nextSpan()
nextSpan()
// let's assume that we're in a thread Y and we've received
// the `initialSpan` from thread X. `initialSpan` will be the parent
// of the `newSpan`
Span newSpan = null;
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(initialSpan)) {
newSpan = this.tracer.nextSpan().name("calculateCommission");
// ...
// You can tag a span
newSpan.tag("commissionValue", commissionValue);
// ...
// You can log an event on a span
newSpan.annotate("commissionCalculated");
}
finally {
// Once done remember to finish the span. This will allow collecting
// the span to send it to Zipkin. The tags and events set on the
// newSpan will not be present on the parent
if (newSpan != null) {
newSpan.finish();
}
}
创建此类 span 后,必须完成它。否则,不会报告(例如,向 Zipkin)。 |