
Jaeger Agent 启动失败:端口被占或协议不匹配
本地跑 jaeger-agent 时常见报错 address already in use 或根本收不到 span,大概率是 UDP 端口 6831(Thrift Compact)没通,或者客户端发的是 6832(Thrift Binary)但 agent 没开对应监听。
- 默认只监听
6831,Go 客户端用jaeger-client-go时默认也走这个端口,不用改 - 如果用
docker run jaegertracing/jaeger-agent,记得加-p 6831:6831/udp,TCP 端口(如14271)是 health check 用的,不是传 span 的 - Mac 上 Docker Desktop 的 UDP 转发偶尔抽风,可改用
--network=host启动 agent,让 Go 进程直连localhost:6831 - 验证是否收到数据:
tcpdump -i lo0 -n udp port 6831 | head -10(Mac),有输出说明链路通了
Go 应用接入 Jaeger:client 初始化别漏了 reporter 和 sampler
只调 cfg.NewTracer() 不会自动上报,必须显式配置 reporter 指向 agent 地址,否则 tracer 创建成功但所有 span 都静默丢弃。
-
reporter必须设localAgentHostPort,比如"localhost:6831";不填或填错 host 会导致连接超时,日志里几乎不报错,只能看 tracer.IsStarted() 是否为 false - 开发环境建议用
ConstSampler(param: 1表示全采),避免默认的ProbabilisticSampler把你的调试请求随机过滤掉 - 别在 HTTP handler 里反复 new tracer,全局复用一个
opentracing.Tracer实例即可 - 示例关键行:
cfg := &config.Configuration{ServiceName: "my-service"}<br>cfg.Reporter.LocalAgentHostPort = "localhost:6831"<br>cfg.Sampler.Type = "const"<br>cfg.Sampler.Param = 1<br>tracer, _ := cfg.NewTracer(config.Logger(jaeger.StdLogger))
Span 上下文传递断开:HTTP 请求里没注入/提取 baggage
微服务间调用时 span parent ID 丢失,链路变成多个孤立节点,问题基本出在 HTTP header 的 inject/extract 流程没串起来。
- 用
http.RoundTripper做出站请求时,必须手动调tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header)) - 服务端收到请求后,得用
tracer.Extract(opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header))拿 context,再StartSpanFromContext - 别依赖中间件自动做——
jaeger-client-go不提供开箱即用的 HTTP middleware,得自己 wrap 或用社区轻量封装(如jaeger-http包) - 检查 header 名:Jaeger 默认用
uber-trace-id,不是traceparent(W3C 标准),混用会断链
Docker Compose 部署 Jaeger UI:query 服务连不上 cassandra/es 时先关掉存储
本地快速验证不需要持久化,硬配 Cassandra 或 Elasticsearch 反而卡住启动,jaeger-query 日志刷满 connection refused 却不报具体哪个服务挂了。
立即学习“go语言免费学习笔记(深入)”;
- 直接用 all-in-one 镜像最省事:
docker run -d -p 16686:16686 -p 6831:6831/udp jaegertracing/all-in-one:1.45 - 若必须用 compose,把
query的STORAGE=memory环境变量加上,并删掉对cassandra或elasticsearch的 depends_on 和 links - UI 访问地址永远是
http://localhost:16686,别试:14268(这是 collector 接收 endpoint) - all-in-one 模式下 span 仅内存存储,重启容器就清空,适合调试,不适合压测或跨天观察
Jaeger 的“可视化”其实只是 query 服务把存储里的 span 渲染成前端图表,真正难的是让每个 span 的 traceID、parentID、timestamp 在进程间准确透传——这三样只要有一样没对齐,UI 上就只能看到碎片。










