当前位置: 首页 > 知识库问答 >
问题:

Sleuth在发送给RabbitMQ的消息的b3单个头中不包括ParentSpan

孙永思
2023-03-14

我最近从spring cloud greenwich.sr2迁移到hoxton.sr9,并且正在使用spring Sleuth跟踪传入的对我的spring boot应用程序的REST调用,这些调用触发了最终到达RabbitMQ的消息。

显然,spring Sleuth在这两个版本之间的一个关键区别是,现在只发送一个b3头,格式{trace}-{span}-{sample}-{parentSpan},最后两个组件是可选的,而不是为trace、span和parentSpan发送3个单独的消息头。

令我困惑的是,到达RabbitMQ的消息上的b3头似乎从来没有parentSpan组件。例如,顺序如下所示:

  1. 应用程序REST控制器内:traceid=t,spanid=s1,parentspanid=s0
  2. 从应用程序内部发送事件之前:traceid=t,spanid=s2,parentspanid=s1
  3. RabbitMQ队列上的消息头:b3=t-S2-1

换句话说,消息头具有正确的跟踪,但共享应用程序中发送事件上下文的跨度,并且没有父跨度。

这是意料之中的吗?我确信使用以前版本的Sleuth我会在消息头中看到一个新的spanId和一个与发送事件上下文中的span相等的parentSpan。

我是否误解了正在发生的事情,或者(如果我认为是合理的)是否有办法改变这种默认行为。

我有以下显式侦测属性设置:

spring.sleuth.enabled=true
spring.messaging.enabled=true
spring.supportsJoin=false

(注意:我尝试了相同的supportsJoin默认值,但似乎对缺少parentSpanId没有任何区别)。

调试信息

这是我在调试器中能够确定的:

  1. 我们将GenericMessage传递到AbstractMessageChannel.send()中。
  2. 消息最终被传递到TracingChannelInterceptor.presend()
  3. TracingChannelInterceptor使用DeferRedInjector配置,其中SetterMessageHeaderPropagation实例,而InjectorFactor具有ProducerInjectorFunction=Single_NO_Parent
  4. TracingChannelInterceptor.Presend()方法调用DeferRedInjector.Inject(Span.Context(),headers),这会导致SINGLE_NO_PARENT注入器将{traceId}-{spanId}-1格式的B3头添加到传出消息。

因此,缺少parentSpanId似乎源于TracingChannelInterceptor.injector是一个DeferredInjector,其生成器injector是Single_NO_Parent。

自定义配置

注册以下bean以覆盖默认传播设置将行为更改为:

  1. 应用程序REST控制器内:traceid=t,spanid=s1,parentspanid=s0
  2. 从应用程序内部发送事件之前:traceid=t,spanid=s2,parentspanid=s1
  3. RabbitMQ队列上的消息头:b3=t-S2-1-S1

但我想知道为什么有必要这么做?

@Configuration
public class B3Configuration {
  @Bean
  Propagation.Factory customPropagationFactory() {
    return B3Propagation.newFactoryBuilder()
        .injectFormat(B3Propagation.Format.SINGLE)
        .injectFormat(Span.Kind.CLIENT, B3Propagation.Format.SINGLE)
        .injectFormat(Span.Kind.CONSUMER, B3Propagation.Format.SINGLE)
        .injectFormat(Span.Kind.PRODUCER, B3Propagation.Format.SINGLE)
        .build();
  }
}

共有1个答案

裴曜灿
2023-03-14

默认的b3propagation.format似乎已更改,您可以在TraceBaggageConfiguration中看到当前的:

// Note: Versions <2.2.3 use injectFormat(MULTI) for non-remote (ex spring-messaging)
// See #1643
static final Propagation.Factory B3_FACTORY = B3Propagation.newFactoryBuilder()
        .injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();

您可以跟随细节和更改是在spring-云-侦探#1643。

如果要更改bahavior,我建议创建baggagepropagation.factorybuilder而不是propagation.factory,因为当Sleuth自动配置propagation.factory时,它会做更多的工作,请参阅TraceBaggageConfiguration

例如:

@Bean
BaggagePropagation.FactoryBuilder baggagePropagationFactoryBuilder() {
  return BaggagePropagation.newFactoryBuilder(
          B3Propagation.newFactoryBuilder()
                  .injectFormat(B3Propagation.Format.SINGLE)
                  .build()
  );
}
 类似资料:
  • 我在Spring Boot应用程序中使用sleuth进行日志跟踪,我的应用程序也通过活动MQ发送一些消息,但当我看到消息属性时,它会使用单个b3头发送跟踪。我如何配置sleuth以分离标题?

  • 本文向大家介绍RabbitMQ 的消息是怎么发送的?相关面试题,主要包含被问及RabbitMQ 的消息是怎么发送的?时的应答技巧和注意事项,需要的朋友参考一下 首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 Ra

  • 我在Node中编写的服务很少使用“X-Request-Id”作为标头来识别请求。我现在使用spring boot在Java中编写服务,我可以使用spring cloud sleuth跟踪traceId和spanId。 然而,我希望在我的所有服务中继续使用“X-Request-Id”作为请求标识符。有没有办法在spring sleuth中重命名“X-B3-TraceId”标头,以便它在HTTP请求中

  • null 谁能给我一个向RabbitMQ发送消息的标准程序的例子。我正在使用Spring Boot,也可以使用它的特性。

  • 如何保持一个连续的流,以“反应”新的丢弃的文件?(或其他事件,如HTTP GET请求或类似的事件)... 例如,如果我不返回PublisherBuilder的实例,而是返回一个整数,那么我的kafka主题将由一个非常巨大的整数值流填充。这就是为什么示例在发送消息时使用一些间隔... 我应该使用一些CompletationStage或CompletableFuture吗?RXJava2?使用哪个li

  • 我将使用Zipkin在现有代码中添加Spring Cloud Sleuth,以收集跟踪信息,并最终记录任意消息。正常的请求跨度被正确地发送到Zipkin: 检查Zipkin中的跟踪,可以正确地找到span,但是却看不到行中使用的消息--这表明我在这里做了一些错误的事情,或者它不应该以这种方式工作。我的抽样百分比设置为100%。 使用slf4j接口会很方便,因为现有的代码已经以这种方式检测了。有可能