AlexStocks commented on issue #3240:
URL: https://github.com/apache/dubbo-go/issues/3240#issuecomment-4043005884

   感谢详细的问题分析。这是一个严重的 bug,影响所有使用 Triple 协议的 OTEL 追踪系统。
   
   ## 问题本质
   
   两个独立的缺陷串联发生,导致 traceparent 破坏:
   
   **缺陷 1:parseAttachments 覆盖**
   - `parseInvocation()` → `parseAttachments()` 执行,通过 
`invocation.SetAttachment()` 从 URL 参数和 ctx 复制旧 attachment
   - `mergeAttachmentToOutgoing()` 随后执行,把这些 attachment(包括被覆盖的值)转移到 ctx outgoing 
headers
   - OTEL filter 注入的 traceparent 若存在于 invocation attachment 中,会被 URL 
参数的值**静默覆盖**
   
   **缺陷 2:shared header mutation**
   - `tri.AppendToOutgoingContext()` 不创建新 header,而是在共享的 metadata map 上 append
   - 连续 RPC 调用时,第二次调用的 `AppendToOutgoingContext("traceparent", newValue)` 会导致同一 
key 的多个值
   - gRPC `http.Header.Get()` 返回第一个值,所以总是返回旧的 traceparent
   
   ## 根因分析
   
   **设计缺陷**:`parseAttachments()` 的职责不清晰。它既复制用户上下文中的 attachment,又从 URL 
参数注入预定义值。这种"混写"导致:
   
   1. 无法区分"框架注入"vs"用户传入"vs"filter 生成"的 attachment
   2. 执行顺序依赖,易被破坏
   3. 需要 OTEL filter 在 parseAttachments 之后才能注入(但 filter 链的执行顺序不保证)
   
   ## 解决方案对比
   
   | 方案 | 优点 | 缺点 |
   |------|------|------|
   | **A** 禁止 parseAttachments 复制用户 attachment | 简单,单一职责 | 破坏向后兼容 |
   | **B** parseAttachments 只处理 URL 参数 | 同 A | 同 A |
   | **C** 用 `tri.NewOutgoingContext(ctx, {})` 替代 AppendToOutgoingContext | 消除 
shared header 问题 | 代码变化量大 |
   | **D** OTEL filter 最后执行覆盖 traceparent | 兼容现有代码 | 脆弱,靠 filter order 保证 |
   
   ## 建议方案
   
   采用 **B + C** 的组合:
   
   1. **重构 parseAttachments**:只从 URL 参数设置预定义 attachment,删除对 ctx.AttachmentKey 
的复制。用户 attachment 通过 invocation 直接传入,不需要在此复制。
   
   2. **mergeAttachmentToOutgoing 改用独立 header**:使用 `tri.NewOutgoingContext` 而不是 
`AppendToOutgoingContext`,避免 shared header。
   
   这样 OTEL filter 在 parseInvocation 之前执行,注入的 traceparent 不会被覆盖,也不会被后续调用污染。
   
   ## 后续步骤
   
   需要排查:
   - ctx.AttachmentKey 中的数据是谁在用?(搜索代码库)
   - 是否有用户依赖"ctx attachment 被自动复制到 invocation"?
   
   如果无人依赖,方案 B+C 风险最低。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to