Jaeger在Go中跑不起来主因是tracer初始化失败或context传递错误:需显式检查tracer非nil和error,ServiceName不能为空,HTTP中间件须正确提取/注入context,UDP reporter在容器中易丢包,应改用HTTPReporter并动态配置采样。

Jaeger 在 Go 里跑不起来,90% 是 tracer 初始化失败或 context 没传对——不是 tracer 为 nil 导致 panic,就是 span 在 HTTP 调用中彻底丢失。
tracer 初始化必须检查返回值和 error
很多人写完 cfg.NewTracer() 就直接赋给全局变量,结果 UDP 连不上 agent、ServiceName 为空、或 LocalAgentHostPort 配错,NewTracer 返回 nil + err == nil(Jaeger 的设计缺陷),后续调用 StartSpan 立刻 panic。
- 永远要显式判断:
if tracer == nil || err != nil,不能只看err -
ServiceName必须是非空字符串,填""或留零值,UI 里全显示为unknown_service - 别在
init()函数里初始化 tracer:配置项(如环境变量)可能还没加载,建议放在main()开头或启动时的初始化函数中 - 本地调试加一句:
log.Printf("global tracer: %v", opentracing.GlobalTracer()),确认不是<nil>
HTTP 中间件必须正确提取和注入 context
现象是 Jaeger UI 里 trace 只有一层、下游服务完全没数据——本质是 span 上下文没串起来。
- 提取要用
tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header)),别手动读X-B3-TraceId或uber-trace-id - 注入靠
req = req.WithContext(opentracing.ContextWithSpan(req.Context(), span)),再把新req传给 next handler - 中间件必须包裹整个 handler 链;如果在 middleware 里
StartSpan,但 handler 的 error 分支漏掉span.Finish(),span 会卡住不上报 - 所有下游 HTTP 调用前,必须用
tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))注入 header,否则链就断了
UDP reporter 在容器/网络隔离环境下极易静默丢包
Docker 或 Kubernetes 里用 localhost:6831 基本必挂——容器内 localhost 指自己,不是宿主机,也找不到 jaeger-agent 服务。
立即学习“go语言免费学习笔记(深入)”;
- Docker Compose 环境下,
LocalAgentHostPort应设为jaeger-agent:6831(服务名) - 确认 jaeger-all-in-one 容器确实暴露了
6831/udp:启动命令要有-p 6831:6831/udp - Agent 默认监听
0.0.0.0:6831,不是127.0.0.1:6831;只有 host 网络模式才可用localhost - 生产环境强烈建议换
jaeger.NewHTTPReporter:基于 HTTP POST 更可靠,失败会报错,不会静默丢弃
采样配置别硬编码,优先走环境变量
硬写 Param: 1 在生产环境会导致上报爆炸,而写死 0 又查不到问题。动态采样才是常态。
- 支持的环境变量有:
JAEGER_SAMPLER_TYPE=probabilistic、JAEGER_SAMPLER_PARAM=0.01(1%)、JAEGER_SAMPLER_MANAGER_HOST_PORT=jaeger-agent:5778(远程采样) - 代码里用
config.FromEnv()自动加载,比手写SamplerConfig更安全 - 调试阶段可用
const类型,但上线前务必切到probabilistic或rateLimiting - 注意:
LogSpans: true只打日志不上报,适合验证 tracer 是否初始化成功,但别长期开着
真正难的不是写几行 StartSpan,而是 tracer 生命周期管理、context 跨 goroutine 传递、以及 reporter 在不同网络拓扑下的容错行为——这些地方一错,trace 就断得无声无息。


















