9. 跨度生命周期

您可以通过以下方式对 Span 进行以下作:brave.Tracer:spring-doc.cadn.net.cn

Spring Cloud Sleuth 创建了一个Tracer给你的。为了使用它,您可以自动连接它。

9.1. 创建和完成跨度

您可以使用Tracer,如以下示例所示:spring-doc.cadn.net.cn

// 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 的父级。spring-doc.cadn.net.cn

创建跨度后始终进行清洁。此外,请始终完成要发送到 Zipkin 的任何跨度。
如果 span 包含的名称大于 50 个字符,则该名称将截断为 50 个字符。 你的名字必须明确具体。大牌会导致延迟问题,有时甚至会导致异常。

9.2. 连续跨度

有时,您不想创建新的跨度,但又想继续创建一个跨度。这样的一个例子 情况可能如下:spring-doc.cadn.net.cn

  • AOP:如果在达到某个方面之前已经创建了一个跨度,您可能不想创建新的跨度。spring-doc.cadn.net.cn

  • Hystrix:执行 Hystrix 命令很可能是当前处理的逻辑部分。 事实上,它只是一个技术实现细节,您不一定希望将其作为一个单独的存在反映在跟踪中。spring-doc.cadn.net.cn

要继续跨度,您可以使用brave.Tracer,如以下示例所示:spring-doc.cadn.net.cn

// 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. 创建具有显式父级的跨度

您可能希望启动一个新跨度并提供该跨度的显式父级。 假设一个 span 的父级位于一个线程中,并且您想在另一个线程中启动一个新 span。 在《勇敢》中,每当你调用nextSpan(),它会创建一个 span 以引用当前作用域内的 span。 可以将 span 放入作用域中,然后调用nextSpan(),如以下示例所示:spring-doc.cadn.net.cn

// 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)。