共计 2065 个字符,预计需要花费 6 分钟才能阅读完成。
核心概念:理解分布式追踪的黄金指标
分布式系统的可观测性建立在四大黄金指标之上,它们就像医生检查身体的体温、血压等基础指标一样重要:

- 延迟(Latency):请求从发起到响应的时间,直接影响用户体验
- 错误(Errors):系统处理请求时发生的异常情况
- 流量(Traffic):系统正在处理的请求量或并发量
- 饱和度(Saturation):系统资源的使用程度,如 CPU、内存等
OpenTelemetry 是目前最主流的开源观测框架,它由三部分组成:
- API 层:定义统一的埋点接口规范
- SDK 层:实现数据采集、处理、导出等核心功能
- 导出器:将数据发送到后端系统如 Jaeger、Zipkin
痛点场景:为什么我们需要分布式追踪
假设一个电商系统包含订单、支付、库存三个服务,当用户投诉 ” 支付失败 ” 时:
- 没有追踪系统:需要人工查看三个服务的日志,耗时且难以关联
- 有追踪系统:通过 TraceID 一键查询完整调用链,快速定位是库存服务超时导致了支付回滚
技术实现:从代码层面接入追踪
Go 语言自动埋点示例
package main
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/trace"
)
func initTracer() (*trace.TracerProvider, error) {exp, err := jaeger.New(jaeger.WithCollectorEndpoint())
if err != nil {return nil, err}
tp := trace.NewTracerProvider(trace.WithBatcher(exp),
// 采样率设置为 100%
trace.WithSampler(trace.AlwaysSample()),
)
otel.SetTracerProvider(tp)
return tp, nil
}
// 在 main 函数中初始化
tracer := otel.Tracer("order-service")
ctx, span := tracer.Start(ctx, "ProcessOrder")
defer span.End() // 确保 span 结束
Java 手动埋点示例
@GetMapping("/payment")
public String processPayment(@RequestHeader HttpHeaders headers) {
// 从 HTTP 头提取 TraceContext
Span span = tracer.spanBuilder("payment-process")
.setParent(extractContext(headers))
.startSpan();
try (Scope scope = span.makeCurrent()) {
// 业务逻辑...
span.addEvent("Charge credit card");
return "Success";
} catch (Exception e) {span.recordException(e);
span.setStatus(StatusCode.ERROR);
throw e;
} finally {span.end();
}
}
生产级配置策略
采样策略选择
-
头部采样:在请求开始时决定是否采样,适合流量稳定的系统
# OpenTelemetry Collector 配置示例 processors: probabilistic_sampler: sampling_percentage: 10 -
尾部采样:先收集所有数据再按规则筛选,适合需要保留异常请求的场景
导出器选型建议
- Jaeger:适合需要强大可视化分析的企业
- Zipkin:轻量级方案,适合资源有限的环境
- OTLP:OpenTelemetry 原生协议,未来兼容性最好
避坑指南
- Span 命名规范:
- 使用
serviceName.operationName格式 -
避免动态名称如
/user/123,应改为/user/{id} -
标签使用禁忌:
- 不要记录敏感信息如密码、token
-
控制标签数量(建议不超过 20 个)
-
高并发上下文丢失:
- 使用线程局部变量存储 Context
- 框架集成时检查异步调用链是否完整
验证环节:本地 Jaeger 快速启动
# docker-compose.yml
version: '3'
services:
jaeger:
image: jaegertracing/all-in-one:latest
ports:
- "16686:16686" # UI 端口
- "14268:14268" # 接收数据端口
启动后访问 http://localhost:16686 即可查看追踪数据。
动手实验
尝试实现以下场景:
- 创建两个 HTTP 服务(A 和 B)
- 服务 A 调用服务 B 时,通过 HTTP 头传递 TraceContext
- 在 Jaeger 中确认能看到完整的跨服务调用链
通过这个练习,你会深刻理解分布式追踪的核心价值——让复杂的系统调用变得透明可见。当遇到生产环境问题时,再也不用像无头苍蝇一样到处翻日志了!
正文完
发表至: 技术分享
近三天内
