9. 生命周期跨度
您可以使用brave.Tracer对跨度执行以下操作:
-
start: 当您开始跨度时,会分配名称并记录开始时间戳。
-
close: 该span结束(记录span的结束时间),如果该span被采样,就符合收集条件(例如,发送到Zipkin)。
-
continue: 一个新的跨度实例被创建。它是它继续的那个的副本。
-
detach: 这个跨度不会被停止或关闭。它只是从当前线程中移除。
-
create with explicit parent: 您可以创建一个新的 span 并为其设置显式父级。
Spring Cloud Sleuth 为你创建了一个 Tracer 的实例。要使用它,你可以通过自动装配来获取它。 |
9.1. 创建和结束跨度
你可以通过使用 Tracer 手动创建 spans,如下例所示:
// 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 后进行清理。也请在想要发送到 Zipkin 的任何 span 结束时进行结束操作。 |
| 如果你的跨度包含一个超过 50 个字符的名称,该名称将被截断为 50 个字符。 您的名称必须是明确的和具体的。 大名称会导致延迟问题,甚至有时会出现异常。 |
9.2。继续跨度
有时候,您不想创建新的span而是想继续一个。这种情况的一个例子可能如下所示:
-
AOP: 如果在到达切面之前已经创建了 span,你可能不想创建新的 span。
-
Hystrix: 执行一个 Hystrix 命令很可能是当前处理的逻辑部分。 实际上,这只是一个技术实现细节,你可能不希望将其作为独立实体反映在追踪中。
要继续一个跨度,可以使用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.创建显式父级的跨度
您可能需要开始一个新的跨度并提供该跨度的显式父级。 假设一个跨度的父级在一个线程中,并且您要在另一个线程中启动新的跨度。 在勇敢中,每当您调用 0 时,它都会创建一个与当前范围内的跨度相关的跨度。 您可以将跨度放在范围内,然后调用 1,如以下示例所示:
// 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();
}
}
| 创建完跨度后,必须将其结束。否则将不报告(例如,报告到 ZipKin)。 |