DDTrace 接入观测云:单服务切换、验证与回滚

保留现有 DDTrace 插桩,把一个测试服务的链路发送到 DataKit;逐层核对接收、上传、采样和上下文传播,并保留明确回滚路径。

最佳实践 产品能力
DDTrace 单服务切换与回滚示意图

评估观测云,不必从重写 DDTrace 插桩开始。先保留现有 DDTrace SDK 或 Java Agent,只把一个低风险预发布服务的链路发送地址切到 DataKit。在观测云找到同一组测试请求,核对服务名称、错误和下游调用;条件不满足,就恢复已经记录的原发送地址,并确认旧后端重新收到新的链路。

本文讨论的是单个服务的链路接收端切换。仪表板、监控器、SLO、RUM、可用性监测、Profiling、日志、安全数据、合同和历史记录,都不在自动迁移范围内。配置与协议已于 2026 年 10 月 27 日对照官方文档复核;本轮没有执行应用→DataKit→观测云的实机传输,也没有完成回滚演练。用于生产操作前,需要在自己的预发布环境完成这两项验证。

先分清三个端口

应用继续使用现有 DDTrace 库生成 Span,DataKit 接收和处理链路,再发送到选定的观测云工作空间。DDTrace 采集器文档区分了三条容易混淆的路径。

端口 用途 接错时会发生什么
DataKit HTTP 9529 在配置的 DDTrace 路径接收链路 应用连不上,或 DataKit 没收到链路
Datadog Agent 8126 常见的 Trace Agent 默认端口 数据仍发往旧 Agent,或目标没有监听
DogStatsD 8125 接收指标,包括部分运行时和 JMX 指标 可能有指标,但不会因此收到 DDTrace Span

DataKit 的 ddtrace 采集器负责链路。Profiling 使用独立采集器;运行时指标、JMX 可能需要 StatsD 或其他集成。看到一条链路,只能证明该链路路径可用,不能据此认定两个平台功能完全等价。

把第一次切换限制在一个服务

保留 DDTrace 插桩,通过私有网络把一个服务的链路发往 DataKit,验证观测云中的结果,失败后恢复旧后端
一次只切换一个服务的发送地址,保留旧路径;完成验证后再扩大范围。

保留 SDK 或 Agent,只改测试服务的发送地址。比较期间固定 service、env、version、上下文传播和采样设置,分别检查接收端、上传路径和实际排障过程。触发停止条件,就恢复旧地址。

这不是双写方案。不能假定普通 DDTrace tracer 会把每个请求独立发送给两个后端。若以后需要并行比较,应在服务能输出 OTLP 的阶段单独设计 OpenTelemetry Collector 的多个 exporter,并评估队列、重试、出口流量、接收费用和故障影响。

先约定什么时候停止

选择一个可以独立重启、会调用至少一个下游依赖的非生产服务,例如预发布的登录、商品或结算接口。准备正常请求和可控的测试错误,不使用真实客户数据,也不向生产环境注入故障。

出现以下情况就停止扩大范围,按约定回滚:

  • 必须扩大公网访问规则才能连接 DataKit。
  • 启动、请求延迟或错误率超出团队预先确定的容忍范围。
  • 入口 Span 或已知下游调用缺失,且无法解释。
  • 采样或过滤不同,导致两段数据不可比。
  • 链路属性包含凭据、请求正文或个人信息。
  • 无法在变更窗口内恢复原发送地址。

“等了五分钟”不是成功标准。批处理、网络、缓冲和负载都会影响到达时间,应先测量本环境正常情况下的延迟,再在相同条件下比较。

保存能用于回滚的基线

回滚要依赖实际配置,而不是记忆。未设置的值记为 unset,不要用猜测填补。

项目 变更前记录
应用 语言、运行时、DDTrace 库或 Agent 的准确版本
发送地址 生效的主机、端口或 URL,以及配置来源
服务标识 DD_SERVICE、DD_ENV、DD_VERSION
上下文传播 每一跳实际注入与提取的格式
采样 SDK、接收端规则,以及错误和稀有资源的处理
DataKit 版本、部署方式、监听地址、采集器配置来源
网络 DNS、命名空间或 VPC、防火墙、NetworkPolicy、出口代理
相邻资产 Profiling、运行时指标、日志、仪表板、监控器和 SLO 的处理负责人

只读取必要且不含秘密的配置项,不要把完整环境变量或整个 DD_ 前缀的变量输出到工单、截图或 CI 日志中。

Python tracer 配置说明,设置 DD_TRACE_AGENT_URL 后,它会优先于分开的 host、port。当前 Python、Java、Node.js 文档使用 DD_TRACE_AGENT_PORT,不要照搬旧示例中的 DD_AGENT_PORT。应查看实际安装版本的语言文档,清除冲突地址,并在部署或注入后核对进程的生效配置。

启用 DataKit DDTrace 接收端

主机安装方式下,从 DataKit 的 conf.d/samples 复制 ddtrace.conf.sample,以 ddtrace.conf 管理。最小配置保留兼容路径:

[[inputs.ddtrace]]
  endpoints = ["/v0.3/traces", "/v0.4/traces", "/v0.5/traces"]

  # 只提取确有用途、稳定且基数较低的属性。
  # customer_tags = ["team", "deployment.region"]

不要为了让配置更短而删除 endpoint。也不要留下缺少采样率的 [inputs.ddtrace.sampler] 表:缺失的 rate 会按 0 处理。不打算在接收端采样,就移除或注释掉整个表。

错误链路默认会绕过这个 sampler,配置 omit_err_status 后相应状态不再享有该例外;上游 sampling priority 引发的提前丢弃又是另一层判断。因此,接收端 rate 为 1.0 也不能证明每个应用请求都会进入观测云。

按既有 DataKit 配置流程应用变更,只重启受影响的实例。用状态管理确认 ddtrace 已启用、没有崩溃和新增初始化错误:

datakit monitor --input ddtrace

记录版本、输入状态、错误计数变化和测试时间窗口,不把某张截图当成唯一成功标准。

9529 只开放给需要连接的工作负载

DataKit 默认监听 localhost:9529。应用和 DataKit 同主机时可使用该地址;跨 Pod 或跨主机时,需要可达的监听地址:

[http_api]
  listen = "0.0.0.0:9529"

0.0.0.0 只是监听范围。还需用 Kubernetes Service、NetworkPolicy、安全组或主机防火墙限制来源,不能直接向公网开放链路接收端。同一 HTTP 服务可能提供其他 DataKit API,过宽的入口规则会影响更多功能。

Kubernetes 中可以使用私有 ClusterIP Service。以下片段的 namespace 和 selector 必须与实际部署一致:

apiVersion: v1
kind: Service
metadata:
  name: datakit-trace
  namespace: observability
spec:
  type: ClusterIP
  selector:
    app: datakit
  ports:
    - name: datakit-http
      port: 9529
      targetPort: 9529

从测试服务所在的网络环境检查 DNS 与 HTTP 可达性:

curl --fail --silent --show-error \
  --output /dev/null --write-out '%{http_code}\n' \
  http://datakit-trace.observability.svc.cluster.local:9529/v1/ping

/v1/ping 返回运行信息,只能确认 HTTP 服务可达,不能证明 DDTrace 采集器接受了 Span。不要为了得到响应而放宽访问控制。

切换发送地址,保持服务标识不变

在当前 tracer 支持的形式中选一种,不要同时保留两组地址。以下占位值须替换为变更前记录的实际值。

export DD_AGENT_HOST="datakit-trace.observability.svc.cluster.local"
export DD_TRACE_AGENT_PORT="9529"
export DD_SERVICE="<existing-service>"
export DD_ENV="<existing-env>"
export DD_VERSION="<existing-version>"

# 按既有流程启动或部署该测试服务。

如果使用的 tracer 支持 URL 形式,也可以选择:

export DD_TRACE_AGENT_URL="http://datakit-trace.observability.svc.cluster.local:9529"
export DD_SERVICE="<existing-service>"
export DD_ENV="<existing-env>"
export DD_VERSION="<existing-version>"

# 按既有流程启动或部署该测试服务。

比较期间保持原 SDK 采样规则不变。如果同时改服务名称、环境或采样,链路缺失就可能来自检索条件和分组变化,而非发送路径。需要 100% 采样时,另做低流量实验并记录范围。

接收端可达不代表 tracer 已加载。检查最终运行命令:Java 的 -javaagent 要位于 -jar 之前;Node.js 的 dd-trace 要先于被插桩模块初始化;Python 保留原来的 ddtrace-run 或框架集成,ddtrace-run --info 仅用于配置检查。使用注入时,核对实际 NODE_OPTIONS 等启动参数。Guance Operator 的注入变更作用于新建 Pod,应只重建测试 Pod,不要假定已有 Pod 会原地改变。

用正常请求和可控错误验证

选择不含客户标识的预发布接口、合成事务或测试夹具。请求量只需足以观察采样,不要无意间变成压测:

for attempt in 1 2 3 4 5; do
  curl --fail --silent --show-error \
    "https://staging.example.test/health/trace-canary?attempt=${attempt}" \
    --output /dev/null
done

把示例 URL 换成自己的测试接口,再调用一次已知状态码与下游行为的可控错误路径。记录请求时间、预期状态、入口资源和下游服务,不保存敏感请求正文。

正常请求用于检查入口和拓扑;错误请求检查错误分类及保留行为;下游调用检查上下文传播和父子关系。

分开检查接收、上传和查询

第一步,在 datakit monitor --input ddtrace 和运行日志中确认输入持续启用,测试期间没有新增错误。无数据排查可帮助区分启动、采集器、监听、时间和网络问题。

第二步,检查 DataKit 到选定站点的 DataWay 出口、代理、时间同步、队列和错误信号。接收端正常不代表上传成功;记录证据时不要复制工作空间凭据。

第三步,在目标工作空间的链路查看器中选择测试时间,用原先记录的 service、env、version 筛选。至少确认:

  • 存在非空 Trace ID,服务标识与实际发送值一致。
  • 能查看入口 Span 的资源、耗时、状态和错误。
  • 已知下游关系存在,缺失时有明确解释。
  • 可以找到可控错误产生的错误链路。
  • 整个测试期间 SDK 与接收端采样规则没有改变。

截图需脱敏。两边的请求集合和采样条件不同,不能只比较 Trace 总数。

沿着数据路径排障

现象 优先检查 后续动作
DataKit 没有链路 tracer 是否加载、生效 URL/主机/端口、9529 可达性 排除旧 URL 覆盖,修正 DNS 或端口,必要时回滚
input 不存在或崩溃 配置文件、TOML、重启结果 先修复接收端,再改应用
接收正常但观测云无数据 DataWay 出口、代理、时钟、工作空间和时间范围 修复上传或查询条件,不扩大入口权限
只看到部分实例 各实例的配置与 tracer 版本 缩小到同一版本的一组实例验证
服务拓扑断开 注入/提取格式、64/128 位 Trace ID 对齐传播方式,验证一条完整调用路径
数量明显偏少 SDK、接收端采样和过滤、错误处理 固定两层规则后再比较
属性只在 Span 元数据中 customer_tags、数据类型和基数 只提取必要的稳定属性
没有 Profiling 或运行时指标 信号对应的独立采集器 另行配置,不能靠切换 Trace 地址完成

一次只改一个变量。多个设置同时变动后恢复正常,很难知道哪一项起了作用。

DDTrace 与 OpenTelemetry 共存时保住父子关系

采集成功仍可能出现拓扑断裂。Datadog、W3C tracecontext、B3 的支持范围和默认值要按语言与版本确认。DataKit 提供以下关联设置:

[[inputs.ddtrace]]
  endpoints = ["/v0.3/traces", "/v0.4/traces", "/v0.5/traces"]
  compatible_otel = true
  trace_128_bit_id = true

compatible_otel 让 Span ID 和 Parent ID 使用十六进制表示;trace_128_bit_id 在 DDTrace 元数据携带 _dd.p.tid 高位时重建完整 ID。要按实际传播协议配置,然后发出一条跨 DDTrace/OpenTelemetry 边界的请求,检查父子调用链。设置存在不等于兼容性已经验证。

不要一次替换所有服务的 propagator。逐条调用路径推进,并保留旧注入、提取配置供回滚。

同时控制采样和标签

SDK 与 DataKit 的采样独立。SDK 留下一半、接收端再从剩余数据留下一半,并不等于最终保留了一半;错误和稀有资源的例外也会改变结果。

比较时固定请求集合、SDK 规则、DataKit sampler/filter、服务标识、传播设置及属性名单。DataKit 1.21.0 起不再自动把全部 Span 元数据提取到顶层,1.22.0 起可用 customer_tags 选择条目。meta 中的字符串成为标签,metrics 中的数值成为字段,名称中的 . 转为 _,如 deployment.region 变成 deployment_region。

用户 ID、请求 ID、会话 ID 不应批量提取为顶层标签。可搜索并不意味着值得承担高基数和隐私风险。

新加坡与东南亚部署还要检查出口路径

应用到 DataKit 尽量保持在同一主机、集群或受控网络内;DataKit 到 DataWay 是另一条出口路径。记录工作负载的云地域、VPC、集群、工作空间站点、实际 DataWay 地址、DNS、代理、TLS 检查和出口白名单,还要确认跨境传输、留存、支持和私有部署是否有合同要求。

观测云 OpenAPI 列表把 Asia Pacific Region 1 标为 Singapore,但该标签不能证明某一工作空间的全部存储、处理、备份位置或合同承诺。本文针对新加坡场景,也不因此承诺数据驻留;应以适用合同和区域服务信息为准。

使用企业代理时,遵循DataKit 代理配置,验证正常 DataWay 路由,不在工单中贴 Token、完整含凭据的 DataWay URL 或代理密码。

OpenTelemetry 是后续决策

第一次切换要回答:现有 DDTrace 链路是否能支持观测云中的故障调查。之后再决定哪些服务保留 DDTrace、哪些改用 OpenTelemetry,以及是否调整采集层。

OpenTelemetry Collector支持多个 pipeline 和 exporter,能在服务输出 OTLP 后开展并行评估,但会增加队列、出口流量、接收、存储成本和故障路径。它不保证零丢失或免费复制。

通过 DataKit 接收 OTLP 时,核对官方集成文档中的版本、协议、端口和 /otel 路径。不要把普通 DDTrace payload 发往 OTLP endpoint,也不能把 Preview exporter 当作所有语言通用的迁移桥梁。

旧后端重新收到新链路,才算回滚完成

  1. 只为测试服务恢复原 URL、主机、端口、传播与采样设置。
  2. 按原发布流程重启或重新部署该服务。
  3. 重新发送正常请求与可控错误请求。
  4. 在旧后端确认新链路、服务标识和下游 Span 正常。
  5. 考虑正常缓冲延迟后,确认观测云不再收到新的测试链路。
  6. 旧路径稳定后,再清理临时配置和网络许可。

常见 Datadog Agent 路径可能是原主机加 DD_TRACE_AGENT_PORT=8126,也可能使用 URL;必须恢复变更前真正生效的值。关闭 Operator 注入注解也需重建 Pod。DD_TRACE_ENABLED=false 只关闭追踪,不会把数据发回 Datadog。

如果 Kubernetes 的目标 revision 只包含这次地址切换,可以有针对性地撤回:

kubectl rollout status deployment/checkout-api --namespace staging

# 仅在记录的 revision 只包含发送地址变更时使用。
kubectl rollout undo deployment/checkout-api --namespace staging

若同一 revision 包含业务变更,不能盲目撤回。旧 Agent、监控器和原配置要保留到回滚演练结束。

扩大范围前,留下可复核的评估记录

可以安排覆盖日常流量、发布和故障调查的约 30 天评估,但时间长短不能替代证据。检查主要接口覆盖、正常与错误查询、超时和慢链路、混合传播拓扑、DataKit 资源与出口、敏感属性、相邻信号、回滚及成本。

每项都应有可追溯结果:关键路径缺口有解释;团队能复现一次已知故障的调查;CPU、内存和队列没有持续饱和;日志、指标、Profiling、仪表板、监控器、SLO 有保留、重建或退出方案;旧后端在回滚后收到新数据。成本模型使用相同流量、信号范围、采样、留存和并行运行周期。

哪些已经有文档依据,哪些仍需自己的证据

端口、协议路径、属性提取、Python 的 URL 优先级已有官方依据。真正需要现场验证的是:准确的运行时/SDK/DataKit 组合、部署后的生效设置、采样与传播、负载下的丢失和延迟,以及回滚。

合同、工作空间地域、存储和处理位置、SLA、支持与私有部署条款,应通过客户对应资料确认;一次链路测试无法回答这些问题。仪表板、监控器、SLO、RUM、可用性监测、日志、Profiling、安全和历史记录的迁移,也需要独立方案。

因此,本文不承诺全功能直接替换、一键迁移、零停机、无丢失、默认双写或必然降本。缺少证据就保持小范围,设计能回答该问题的下一项测试。

把技术验证接回选型

新加坡 Datadog 替代方案讨论运行模式与取舍,新加坡价格指南解释站点、计费和估算假设,本文负责接收端切换、验证与回滚。

三方面条件都成立后,再结合观测云 APM确定拓扑、安全、区域约束和下一批服务。一个服务成功,不代表整个 Datadog 平台已经可以退出。

官方资料

以下配置与协议资料于 2026 年 10 月 27 日复核;这项复核不包含实机兼容或合同审核。

  1. TrueWatch DDTrace;观测云 DDTrace:接收范围、端口、采样、属性和 ID。
  2. Datadog Python、Java、Node.js:发送地址、优先级和启动配置。
  3. Datadog SDK;上下文传播:语言接入与跨服务传播。
  4. Operator DDTrace 注入;状态管理:Pod 注入和采集器检查。
  5. DataKit 无数据排查;架构;HTTP API:接收、上传与可达性边界。
  6. 链路查看器;OpenAPI 站点;代理配置:查询、地域标签与网络。
  7. OpenTelemetry Collector;配置;DataKit OpenTelemetry:并行 exporter 和 OTLP 接入。
获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台