Jaeger 客户端初始化必须显式设置 service name,否则上报失败;HTTP trace context 需手动注入/提取;采样策略须创建 tracer 前配置;span 必须显式调用 Finish() 否则不上报。

Jaeger 客户端初始化必须指定 service name
不设 service name 会导致上报失败,Jaeger UI 中完全看不到服务名,甚至 span 被丢弃。它不是可选参数,而是服务注册的唯一标识。
常见错误是直接用 jaeger.NewTracer() 而没传 config.ServiceName,或误把主机名、进程 PID 当作 service name。
- 必须在
jaeger.NewConfig()中显式设置ServiceName: "your-api-service" - service name 应该稳定、语义清晰,避免含特殊字符或动态值(如时间戳、随机数)
- 若用环境变量控制,确保启动时已加载,不要在 tracer 初始化后才读取
HTTP 请求拦截需手动注入/提取 trace context
Go 标准库 http.Client 和 http.ServeMux 不自动传播 trace headers,必须自己调用 tracer.Inject() 和 tracer.Extract()。
漏掉任一端,链路就会断成两截:上游 span 无法关联下游 span。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 客户端发请求前:用
tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header)) - 服务端收请求时:用
tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header))恢复上下文 - 别依赖中间件自动处理——除非你明确集成了
jaeger-client-go提供的httptrace或gin-gonic等适配器
采样策略要提前配置,否则默认只采 1%
本地开发时看到 trace 很少,大概率是采样器没调对。const` 采样器设为 <code>On 最简单;线上则推荐 probabilistic 或 rate-limiting 配合 jaeger-agent。
注意:jaeger-client-go 的采样配置必须在 tracer 创建前完成,运行时无法热更新。
- 开发期快速验证:用
jaeger.NewConstSampler(true) - 生产环境避免全量采样:设
jaeger.NewProbabilisticSampler(0.01)(1%) - 若用
agent模式,采样决策由 agent 统一做,client 端应配RemoteControlledSampler
span finish 前必须显式调用 span.Finish()
忘记调用 span.Finish() 是最隐蔽的链路“消失”原因——span 会滞留在内存里,不上报,也不超时自动清理(除非启用了带 timeout 的 wrapper)。
尤其在 defer 场景下,容易因 panic 或提前 return 导致 defer 未执行。
- 总是用
defer span.Finish(),且放在span := tracer.StartSpan(...)后立刻写 - 避免在 goroutine 中启动 span 后不 finish(goroutine 可能早于主流程结束)
- 若 span 生命周期跨函数,务必把
span作为参数透传,并在最终出口处 finish

















