本文定位:面向已经有微服务、网关、日志和基础监控,但还缺少跨服务调用链定位能力的研发、平台和 SRE 团队。
OpenTelemetry链路追踪要解决的问题,是把一次请求在多个服务、线程、异步任务和外部依赖之间的传播路径还原出来。单个服务日志只能说明“我这里发生了什么”,指标只能说明“整体状态是否异常”,而 Trace 能回答“请求经过了哪些组件、每一段耗时多少、错误在哪个 Span 出现”。
一、先明确 OpenTelemetry链路追踪解决什么痛点
微服务排障常见的困难,是现象和根因不在同一个服务里。用户看到接口慢,网关只知道上游超时,业务服务只记录到调用下游失败,下游数据库又没有关联到同一次请求。没有统一 trace_id 时,团队只能在多个日志系统和仪表盘之间手工拼接时间线。
OpenTelemetry 的价值在于提供统一的可观测数据规范和 SDK,让不同语言、框架和基础设施都能用一致方式生成 Trace、Metric 和 Log 信号。本文聚焦 Trace 接入,目标是让微服务请求路径可见、耗时分布可解释、错误位置可定位。

图1:一次请求从网关进入后在多个微服务之间传播 Trace 上
如果你还在补齐指标和告警体系,可以先结合站内微服务可观测性怎么规划理解日志、指标、追踪和 SLO 的分工;本文重点放在追踪接入与排障实践。
二、接入前先设计 Trace 数据口径
很多团队接入 OpenTelemetry 的第一个问题,不是代码怎么改,而是数据口径没有统一。不同服务生成的 service.name 不一致,环境标签有的叫 env、有的叫 environment,错误状态有的写在 Span status,有的只写日志,最后在追踪后端里仍然无法按服务、环境和版本检索。
接入前至少统一:
- 服务标识:service.name、service.namespace、service.version 应稳定可读。
- 环境维度:production、staging、test 等环境命名保持一致。
- 资源属性:Kubernetes namespace、pod、container、node 等由 Collector 或自动探测补充。
- 传播协议:优先使用 W3C Trace Context,减少跨语言断链。
- 隐私边界:不要把身份证号、手机号、Token、完整请求体等敏感内容写入 Span 属性。
这一步看似偏治理,但会直接决定后续排障效率。没有统一资源属性,Trace 后端很难按团队、服务、版本、命名空间过滤;没有传播协议约束,跨 HTTP、gRPC、消息队列时就容易断链。
三、从自动埋点开始,再补关键业务 Span
OpenTelemetry 接入通常有两条路径:自动埋点和手动埋点。自动埋点通过 Java Agent、语言 SDK 或框架插件捕获 HTTP、gRPC、数据库、消息队列等常见调用;手动埋点用于补充业务关键步骤、复杂异步流程和默认插件覆盖不到的边界。

图2:自动埋点先覆盖通用依赖,手动埋点补齐业务关键路径
建议采用“先自动、再手动、最后治理”的顺序:
- 先选一个低风险服务试点:优先选择流量稳定、依赖清晰、排障价值高的服务。
- 启用自动埋点:确认入口请求、下游 HTTP/gRPC、数据库调用能生成 Span。
- 验证上下文传播:检查 trace_id 是否能跨服务延续,是否在异步任务中断开。
- 补充业务 Span:在订单校验、库存锁定、支付回调、规则计算等关键步骤加手动 Span。
- 统一错误标记:异常要体现在 Span status、exception event 或关键属性里。
示例:应用接入时关注的配置项
不同语言配置方式不同,但核心项类似。以下是接入时需要确认的配置含义,而不是要求所有服务复制同一份参数:
service:
name: order-service
namespace: retail
version: 1.8.3
exporter:
endpoint: http://otel-collector:4317
propagation:
format: tracecontext,baggage
sampling:
strategy: parentbased_traceidratio
ratio: 0.1
配置重点是 service 标识、导出地址、传播格式和采样策略。生产环境不要直接默认全量采样所有服务,也不要在没有验证的情况下把 Span 属性写得过细。
四、Collector 是接入链路的缓冲和治理层
OpenTelemetry Collector 位于应用和后端存储之间,负责接收、处理、导出观测数据。它能让应用侧不直接绑定某个追踪后端,也能在发送前完成批量、限流、属性补充、过滤和多目标导出。

图3:Collector 通过 receiver、proces
Collector 配置通常由三部分组成:
- Receiver:接收 OTLP、Jaeger、Zipkin、Prometheus 等不同协议的数据。
- Processor:批量发送、内存限制、属性处理、资源补充、采样、过滤。
- Exporter:发送到 Jaeger、Tempo、Zipkin、Prometheus、日志系统或商业可观测平台。
生产环境建议重点关注:
- 批量与内存保护:使用 batch、memory_limiter 避免后端抖动拖垮 Collector。
- 资源属性补齐:在 Kubernetes 环境中补充 namespace、pod、node 等属性,方便关联排障。
- 采样位置选择:头部采样适合控制总体成本,尾部采样适合保留慢请求和错误请求。
- 多后端导出:迁移或评估阶段可同时导出到两个后端,但要控制成本和隐私边界。
如果平台团队正在统一服务入口、发布和负责人信息,也可以参考站内内部开发者平台服务目录怎么建的思路,把 service.name、Owner、环境和运行时元数据关联起来,减少追踪数据“有链路但没人处理”的问题。
五、采样策略决定成本和排障完整性
Trace 数据量通常比团队预期更快增长。一个入口请求如果经过十几个服务,每个服务又包含数据库、缓存、消息队列调用,就可能生成几十到上百个 Span。全量保留虽然排障最完整,但存储和查询成本会迅速上升。
| 采样方式 | 适用场景 | 注意事项 |
|---|---|---|
| 固定比例采样 | 流量稳定、成本敏感的服务 | 可能漏掉低频错误 |
| 父级采样 | 保持上下游决策一致 | 入口采样策略要统一 |
| 尾部采样 | 保留慢请求、错误请求、大 Trace | 需要 Collector 缓冲和更多资源 |
| 按路由采样 | 核心接口高保留,普通接口低保留 | 路由命名要规范 |
采样不是越低越省心
采样比例过低会让排障时找不到关键请求;采样比例过高则会增加成本,并可能影响 Collector 和后端稳定性。更合理的方式是按服务等级、接口重要性、错误状态和延迟阈值组合策略:普通成功请求低比例采样,错误请求和慢请求尽量保留,核心交易链路提高采样覆盖。
六、用 Trace 排查微服务故障的步骤
当用户反馈“接口慢”或“偶发失败”时,可以按 CLEAR/PBDS 的思路从现象回到链路证据:先澄清现象,再定位边界,展开调用路径,最后沉淀规则。
一次典型排障可以这样做:
- 确认入口请求:从网关、API 路由、时间窗口、用户或请求 ID 找到对应 Trace。
- 观察关键耗时:按 Span 时间轴查看耗时最长的服务、数据库或外部依赖。
- 检查错误 Span:查看 status、exception event、HTTP status code、retry 次数。
- 对比同类 Trace:判断是单次异常、某个版本异常,还是某类请求都变慢。
- 关联指标和日志:用 trace_id 回查日志,用服务指标确认是否存在整体性资源问题。
- 沉淀告警和面板:把反复出现的问题转化为 SLO、告警规则或运行手册。
这里要避免一个误区:Trace 不是替代日志和指标。Trace 适合还原路径和耗时,日志适合查看具体上下文,指标适合判断影响面和趋势。三者关联后,排障效率才会明显提升。
七、常见断链原因和修复方法
OpenTelemetry链路追踪接入后,最常见的问题不是“没有任何 Trace”,而是“只有一段 Trace”。这通常说明上下文传播在某个边界断开了。
常见断链位置包括:
- 网关到服务:网关没有透传 traceparent 或旧 B3 header。
- HTTP 到 gRPC:协议转换时没有把上下文写入 metadata。
- 同步到异步:线程池、消息队列、定时任务没有显式传递 context。
- 跨语言调用:不同语言 SDK 使用的 propagator 不一致。
- 代理或安全组件:中间层清理了 tracing header。
修复时不要只在某个服务里“补一个 trace_id 日志”。更好的方式是确认入口、客户端、服务端和异步消费者都使用一致的传播协议,并在集成测试中构造跨服务请求验证 Trace 是否连续。对于关键链路,可以把 trace_id 写入日志 MDC 或结构化字段,方便日志系统反查。
八、上线验收清单
OpenTelemetry 接入上线前至少检查:
- 服务命名:service.name、namespace、version 是否符合统一规范。
- Trace 连续性:入口、服务间调用、异步任务是否保持同一 trace_id。
- Span 质量:关键依赖是否有耗时、状态码、错误事件和必要属性。
- Collector 稳定性:内存、队列、导出失败、丢弃数据是否可观察。
- 采样策略:错误和慢请求是否能被保留,普通请求成本是否可控。
- 隐私安全:Span 属性和事件不包含敏感请求体、凭证或个人信息。
- 排障入口:告警、日志、指标和 Trace 后端之间是否能互相跳转。
完成这些检查后,OpenTelemetry 才算从“能看到链路”进入“能用于排障”。对平台团队而言,后续还需要把接入模板、默认配置、语言示例和运行手册沉淀下来,避免每个业务服务重复摸索。
小结
OpenTelemetry链路追踪的落地路径可以概括为:先统一服务标识、环境属性和传播协议,再用自动埋点覆盖通用依赖,通过手动埋点补充业务关键 Span,之后用 Collector 做接收、处理、采样和导出,最后把 Trace 与日志、指标、告警和服务负责人关联起来。真正能提升排障效率的,不只是接入 SDK,而是让链路数据稳定、可检索、可解释,并能进入团队的日常故障处理流程。
常见问题
1. OpenTelemetry链路追踪必须全量采样吗?
不必须。全量采样排障最完整,但成本高,流量大时也可能影响 Collector 和后端。生产环境更常见的是按比例、错误、慢请求、核心接口组合采样,并根据服务等级动态调整策略。
2. 自动埋点够用吗,还需要手动埋点吗?
自动埋点适合快速覆盖 HTTP、gRPC、数据库和消息队列等通用依赖,但它不了解业务语义。订单校验、库存锁定、风控判断、任务编排等关键步骤通常需要手动 Span,才能在 Trace 中解释业务耗时和失败原因。
3. Trace 和日志如何关联?
常见做法是在应用日志中写入 trace_id 和 span_id,并让日志系统把它们作为结构化字段索引。排障时可以从 Trace 跳到相关日志,也可以从错误日志反查完整调用链。需要注意的是,关联字段应来自统一上下文,不要每个服务自行生成独立请求 ID。
4. Collector 应该部署成 DaemonSet 还是集中网关?
两种方式都可以。DaemonSet 适合贴近节点收集、降低应用到 Collector 的网络路径;集中网关便于统一出口、策略和多后端导出。生产环境也常见 Agent + Gateway 两层模式:节点侧负责接收和初步处理,网关侧负责采样、路由和导出。
权威参考资料
- OpenTelemetry 官方文档
- OpenTelemetry Concepts
- OpenTelemetry Traces
- OpenTelemetry Collector
- W3C Trace Context