jaeger客户端初始化报nil pointer dereference的根本原因是jaeger.newtracer()返回nil且未检查,导致后续调用panic;servicename为空则ui显示unknown_service;udp端口6831未暴露、context未正确注入、采样器未在tracerprovider创建时配置均会导致数据丢失或全量上报。

Jaeger客户端初始化报 nil pointer dereference 怎么办
根本原因是 jaeger.NewTracer() 返回了 nil,但代码没检查就直接传给 opentracing.SetGlobalTracer() 或调用 tracer.StartSpan()。
它不报错、不 panic,只在第一次调用时崩——尤其多 goroutine 场景下,你以为 tracer 已就绪,其实 reporter 连不上 agent 就静默失败了。
- 必须显式判断:
if err != nil || tracer == nil,缺一不可 - 别在
init()里初始化:配置(比如LocalAgentHostPort)可能还没加载完,tracer就是nil - 用
jaeger.NewRemoteReporter()时,确保sender初始化成功;HTTP transport 失败不会中断流程,但 tracer 会为nil - 推荐跳过
opentracing全局注册,改用 OpenTelemetry 原生接口,otel.Tracer()不会nil,更安全
为什么 Jaeger UI 看不到服务名,全堆在 unknown_service
不是配置漏了,是初始化 tracer 时 ServiceName 为空或没传——Jaeger UI 完全依赖这个字段做分组和筛选,空值一律归到 unknown_service,查都难查。
-
jaeger.NewTracer("my-api", ...)第一个参数必须是非空字符串,建议与二进制名/Deployment 名一致 - 用
config.Configuration方式初始化时,cfg.ServiceName同样不能是""或未赋值 - Docker 部署
jaegertracing/all-in-one时,6831 端口必须暴露(-p 6831:6831/udp),否则 Go SDK 默认 compact 协议发不出去,表面正常,实则无数据
HTTP 中间件里 span 传不下去,span.Context() 总是空
不是中间件写错了,是 context 没“注入”进 request。OpenTelemetry 不自动读 header,你得手动做两件事:从上游提取、再塞回下游请求。
- 入口 handler 必须先提取:
req = req.WithContext(otel.GetTextMapPropagator().Extract(req.Context(), propagation.HeaderCarrier(req.Header))) - 下游 HTTP 调用前,必须注入:
propagation.TraceContext{}.Inject(ctx, propagation.HeaderCarrier(req.Header)) - 中间件顺序很重要:提取逻辑必须在路由匹配之前执行,否则后续 handler 拿不到带 trace 的
ctx - 别依赖
http.DefaultClient:要用otelhttp.WrapClient()包装,否则自动注入失效
采样率设了却还是全量上报,是不是配置没生效
采样器只在 TracerProvider 创建时绑定,改了配置但没重建 provider,老的 HTTP handler、gRPC server 仍用旧实例,自然不生效。
- 采样必须在
sdktrace.NewTracerProvider()里配,例如:sdktrace.WithSampler(oteltrace.ParentBased(oteltrace.TraceIDRatioBased(0.1))) - 确保你用的 exporter(比如
jaeger.New())和 tracer 是同一个TracerProvider实例创建的,别混用 global 和自定义 provider - Jaeger 默认用
AlwaysSample,不设 sampler 就是 100% 上报,没例外 - 如果用的是
jaeger-client-go+opentracing,采样要配在config.SamplerConfig里,不是靠环境变量或运行时开关
最麻烦的从来不是怎么写 tracer,而是 tracer 初始化失败时不报错、span 传不下去时不提示、采样不生效时还全量打日志——这些静默失败点,才是线上排查最耗时间的地方。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











