Jaeger 工具手册
Jaeger v2 先看组件引用
Jaeger v2 建立在 OpenTelemetry Collector 组件模型上。接收器把 Span 交给 pipeline,jaeger_storage_exporter 写入后端,jaeger_query 从后端提供搜索和按 ID 查询。v1 的 SPAN_STORAGE_TYPE、COLLECTOR_OTLP_ENABLED 等环境变量不能原样搬进 v2;官方 Jaeger 2.20 配置文档明确要求使用 Collector 风格 YAML。
本文固定 2.20.0 作为实验基线。应用侧仍应使用 OpenTelemetry SDK 和 OTLP,把后端选择留在 Collector 或平台配置中。Jaeger 支持 Zipkin v2 接口不意味着新应用应该继续绑定 Zipkin Reporter。
all-in-one 证明协议,不证明持久化
先准备一条无真实用户信息的 Zipkin v2 Span:
TRACE_LAB_DIR=$(mktemp -d)
TRACE_ID=463ac35c9f6413ad48485a3953bb6124
SPAN_ID=a2fb4a1d1a96d312
NOW_US=$(($(date +%s) * 1000000))
cat > "$TRACE_LAB_DIR/span.json" <<JSON
[{
"traceId": "$TRACE_ID",
"id": "$SPAN_ID",
"kind": "SERVER",
"name": "POST /checkout",
"timestamp": $NOW_US,
"duration": 820000,
"localEndpoint": {"serviceName": "checkout-api"},
"tags": {"http.method":"POST","http.status_code":"504","deployment.environment":"trace-lab"}
}]
JSON16 或 32 位十六进制 trace ID、16 位 span ID、微秒时间戳和正数 duration 是格式失败时首先核对的字段。启动官方 all-in-one:
docker run -d --name jaeger-lab \
-p 127.0.0.1:16686:16686 \
-p 127.0.0.1:4317:4317 \
-p 127.0.0.1:4318:4318 \
-p 127.0.0.1:9411:9411 \
cr.jaegertracing.io/jaegertracing/jaeger:2.20.0
curl -fsS http://localhost:16686/ >/dev/null
curl -fsS -X POST http://localhost:9411/api/v2/spans \
-H 'Content-Type: application/json' --data-binary @"$TRACE_LAB_DIR/span.json"
curl -fsS "http://localhost:16686/api/traces/$TRACE_ID"POST 通常返回 202,查询应包含 checkout-api 和 POST /checkout。写入成功但查询 404 时,先确认 9411 与 16686 属于同一容器,再看 docker logs jaeger-lab 和短暂异步处理延迟。
docker restart jaeger-lab
curl -i "http://localhost:16686/api/traces/$TRACE_ID"重启后丢失是预期结果。all-in-one 默认使用瞬时内存;接收、查询和重启是三份不同证据,看到 UI 并不能把第三份省掉。
写路径和读路径必须引用同一 backend
Jaeger v2 的关键关系可以缩成下面一份配置:
extensions:
jaeger_storage:
backends:
trace_store:
memory:
max_traces: 100000
jaeger_query:
storage:
traces: trace_store
http:
endpoint: 0.0.0.0:16686
exporters:
jaeger_storage_exporter:
trace_storage: trace_store
queue:
num_consumers: 10
queue_size: 1000
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
service:
extensions: [jaeger_storage, jaeger_query]
pipelines:
traces:
receivers: [otlp]
exporters: [jaeger_storage_exporter]jaeger_storage.backends.trace_store 定义存储,exporter 写入,jaeger_query.storage.traces 读取同一逻辑名。两处引用不同 backend 时,Collector 可以持续成功接收,而 UI 永远空白。正式部署应从对应版本仓库的 OpenSearch、Elasticsearch 或 Cassandra 示例起步,再替换 endpoint、TLS 和 Secret。
搜索存储会为 service、operation、时间和允许检索的 tag 建索引。属性越多、基数越高,写放大、segment 合并、heap 和磁盘成本越高。按 trace ID 精确读取和“过去两小时全部错误请求”不是同一种负载,容量测试必须覆盖真实搜索条件。
primary storage 通常承担较短保留,archive storage 可手动保存少量重要 Trace。Archive 不会自动覆盖全部数据,也不能替代搜索集群 snapshot、恢复演练和生命周期管理。
采样发生在数据到达前
Head sampling 在 Trace 开始时决策,成本低,但不知道请求最终是否失败。Tail sampling 必须先让 Collector 收齐候选 Span,能保留错误和长尾,却消耗更多网络、内存与处理能力。上游已被 head sampling 丢弃的 Trace 不会到达 tail policy,后者无法把它“捞回来”。
如果 tail policy 要识别全部错误,SDK 到执行 tail sampling 的 Collector 之间必须保持全量,或使用不会提前丢弃目标流量的明确策略。容量迫使团队先做低比例 head sampling 时,只能承诺对入选样本继续筛选。
Jaeger v2 支持远程和 adaptive sampling。策略缺失时的默认概率不能靠想象判断,要用固定请求数比较产生、接收、拒绝和落库 Trace 数,并检查父子 Span 是否完整。
搜不到时按共同链路排查
Service 列表为空时,先看应用是否创建并导出 Span,再看 Collector receiver 的 accepted/refused 和 exporter send_failed,最后检查存储写入。按 ID 能查而条件搜索为空,说明接收与精确读取基本正常,问题转向 tag 索引、刷新、时间范围或查询语义。
近期可查、历史不可查时,检查读写 backend 是否一致、搜索集群健康、索引生命周期和存储凭证。出现零散根 Span 通常属于 W3C/B3 传播或异步上下文问题,不应通过扩大存储或调整索引解决。
Jaeger 查询入口和写入入口要使用不同身份与网络权限。Trace 中的 Authorization、Cookie、SQL 参数、完整请求体和个人信息应在源头或 Collector 删除;查询端 RBAC 无法补救已经持久化的敏感属性。
生产角色按负载分开扩展
all-in-one 适合协议实验,不适合用副本数直接放大到生产。Collector 承担接收、处理、排队和写入,Query 承担搜索与读取,两者资源曲线不同:发布峰值会先推高 Collector 写入和队列,事故调查则可能让 Query 与搜索存储突然承受宽时间窗查询。平台应分别观察 receiver accepted/refused、exporter queue、存储写入延迟、Query 请求耗时和搜索扫描量。
增加 Collector 副本前,要确认负载均衡、OTLP 长连接重建和队列是否仍能均匀分布。增加 Query 副本也不能修复底层索引过碎、权限错误或生命周期提前删除。搜索存储的节点、分片、replica、磁盘水位和恢复时间应与 Jaeger 自身 SLO 一起设计;否则 UI 健康只代表查询进程活着。
服务名、operation 和可搜索 tag 是长期查询契约。Pod UID、用户 ID、订单号与完整 URL 不应成为稳定搜索维度。字段规则发生变化时,用固定 Trace 同时验证旧索引与新索引,再决定是否需要重建或双写;不能通过无限放宽动态索引解决一次临时排障需求。
迁移与退出
后端迁移从 Collector 小比例双写开始,比较接收数、完整 Trace 比例、查询延迟、历史窗口和单位成本。新系统通过重启、存储故障和恢复演练后,停止旧写入但保留旧查询;旧数据过期或归档后再撤销查询入口和凭证。
Jaeger v1 到 v2 是配置模型迁移,不是换镜像标签。v1 flags 要转换为 v2 receiver、exporter、extension 和 pipeline,并用独立测试存储验证。回滚通常是把 Collector exporter 切回旧后端,不是删除新索引。
docker rm -f jaeger-lab
if [ -n "${TRACE_LAB_DIR:-}" ] && [ -d "$TRACE_LAB_DIR" ]; then
rm -rf -- "$TRACE_LAB_DIR"
fi清理只适用于本次唯一容器名和临时目录。生产运行要让接收、按 ID 查询、条件搜索、重启持久化、保留和恢复各有独立证据;jaeger_storage_exporter 与 jaeger_query 引用同一 backend,是这条链最基本的不变量。
