Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在多传播协议下,traceid 出现转换异常 #82

Open
lrwh opened this issue May 23, 2024 · 1 comment
Open

在多传播协议下,traceid 出现转换异常 #82

lrwh opened this issue May 23, 2024 · 1 comment

Comments

@lrwh
Copy link
Collaborator

lrwh commented May 23, 2024

DDTrace 默认开启两种传播协议:datadogtraceparent(W3C协议)

在高并发情况下,不同的请求方对 traceId 生成存在“干涉”行为。导致以下请求头,生成的span traceId 不是原来的值

Header

x-datadog-parent-id: 104339551990828450
x-datadog-trace-id: 1635233488710803284
x-datadog-origin: rum

而导致这一问题是因为 DatadogHttpCodec 解码器调用了restore128bTraceId(),致使 traceId 发生了变化。

    protected TagContext build() {
      restore128bTraceId();
      return super.build();
    }

    private void restore128bTraceId() {
      long highOrderBits;
      // Check if the low-order 64 bits of the TraceId, and propagation tags were parsed
      if (traceId != DDTraceId.ZERO
          && propagationTags != null
          && (highOrderBits = propagationTags.getTraceIdHighOrderBits()) != 0) {
        // Restore the 128-bit TraceId
        traceId = DD128bTraceId.from(highOrderBits, traceId.toLong());
      }
    }

而导致方法restore128bTraceId()改写 traceId的主要原因是 propagationTags.getTraceIdHighOrderBits()getTraceIdHighOrderBits()是用于获取 traceId 的高位码。

由于 datadog 协议默认 traceId 是 64 位,而 W3C 协议 traceId 是 128 位的,为了做兼容处理,所以需要补码处理。补码也是依据请求头x-datadog-tags来进行补码的。

从最上面的 Header 来看,并没有x-datadog-tags,也就说改变这一行为是由于其他链路的请求头导致的,propagationTags 参数值受到了影响,由于这个变量没有”及时的恢复或者清空“,导致了这一结果发生。

@lrwh
Copy link
Collaborator Author

lrwh commented May 23, 2024

目前采用临时方案解决:rum端调整为 w3c 协议。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant