Go 用 OpenTelemetry 打通分布式追踪:从 span 链路到采样策略
test12026-10-161 次阅读
为什么需要分布式追踪
一个请求穿过网关、多个服务和数据库,光看各服务的日志很难还原完整路径。分布式追踪把一次请求标记成一条 trace,里面每个环节是一个 span,串起来就能看到耗时都花在哪。
初始化 Tracer
用 OTLP 把数据导出到 Collector,再由 Collector 转发到 Jaeger 等后端。
package main
import (
"context"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/semconv/v1.21.0"
)
func newTracerProvider(ctx context.Context) (*sdktrace.TracerProvider, error) {
exp, err := otlptracegrpc.New(ctx)
if err != nil {
return nil, err
}
res, _ := resource.Merge(
resource.Default(),
resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceName("order-service"),
),
)
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(res),
sdktrace.WithSampler(sdktrace.AlwaysSample()),
)
otel.SetTracerProvider(tp)
return tp, nil
}
在请求里创建 Span
func handleOrder(ctx context.Context, id string) error {
tracer := otel.Tracer("order")
ctx, span := tracer.Start(ctx, "handleOrder")
defer span.End()
span.SetAttributes(attribute.String("order.id", id))
// 子 span:查库
ctx, dbSpan := tracer.Start(ctx, "queryDB")
if err := queryDB(ctx, id); err != nil {
dbSpan.RecordError(err)
dbSpan.SetStatus(codes.Error, err.Error())
return err
}
dbSpan.End()
return nil
}
跨服务传播
HTTP 调用时把 trace 上下文注入请求头,下游服务解析后就能接在同一条 trace 上。
import "go.opentelemetry.io/otel/propagation"
func callDownstream(ctx context.Context, url string) error {
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
_, err := http.DefaultClient.Do(req)
return err
}
工程注意点
- 生产环境别 AlwaysSample,高流量下改成 ParentBased(TraceIDRatioBased(0.1)) 抽样。
- span 名字要有业务含义,避免用动态参数拼名字,否则后端聚合会爆炸。
- 错误要 RecordError 并设 status,否则 Jaeger 里看不出失败。
- BatchSpanProcessor 是异步导出,进程退出前记得 tp.Shutdown 把缓冲刷出去。
T
test1
文章作者
为什么需要分布式追踪 一个请求穿过网关、多个服务和数据库,光看各服务的日志很难还原完整路径。分布式追踪把一次请求标记成...
- 分类
- 技术
- 发布时间
- 2026-10-16
- 字数
- 约 2094 字
- 阅读
- 1 次
