如何用Jaeger 5步跑通分布式追踪:从零到生产部署的完整路径
2026/9/5 18:00:04 网站建设 项目流程

如何用Jaeger 5步跑通分布式追踪:从零到生产部署的完整路径

【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger

用户在群里投诉"下单变慢了",你翻了三小时各服务日志,只看到一堆"上游超时"的半句话。直到你在 Jaeger——CNCF 毕业的分布式追踪平台——里打开那条跨了 7 个服务的调用链:9 秒的总耗时里,有 8.2 秒卡在一句没走索引的 SQL 上。这就是链路追踪和日志的本质区别:日志告诉你"谁报了错",追踪告诉你"时间到底花在哪"。

Jaeger到底是什么 / 解决什么问题

可以把 Jaeger 理解成快递的物流跟踪系统:一个请求在微服务之间流转时,每一站的时间戳和状态都被记录成span,串起来就是一条trace(调用链)。它由 Uber 开发并捐赠给 CNCF,现在基于 OpenTelemetry Collector 构建,原生接收OTLP 协议(gRPC 4317 / HTTP 4318)。

和传统日志方案比:

对比项分散日志Jaeger 分布式追踪
定位"慢在哪"逐服务 grep 后人工拼时间线瀑布图直接看每个 span 耗时
跨服务关联依赖 traceId 手工串联自动聚合为一条完整链路
服务依赖关系看不出来依赖图直接展示

核心能力:

  • 调用链查询与瀑布图:按服务、操作、标签、时间窗过滤,逐 span 查看耗时
  • 服务性能监控(SPM):从 trace 数据直接算出 RED 指标(请求率、错误率、延迟分位数)
  • 多种存储后端:memory、Badger、Elasticsearch、OpenSearch、Cassandra、ClickHouse
  • 灵活采样策略:概率采样、自适应采样、尾部采样,控制高流量下的数据量

从零跑起来:最小可用环境

准备:一台装了 Docker 的机器就够了

确认端口空闲:16686(UI 和查询 API)、4317(OTLP gRPC)、4318(OTLP HTTP)。

启动:一键拉起 Jaeger All-in-one

一条命令启动包含 UI、Collector、Query、内存存储的 all-in-one 容器:

docker run --rm --name jaeger \ -p 16686:16686 \ -p 4317:4317 \ -p 4318:4318 \ jaegertracing/jaeger:latest

接入应用:OTLP 是唯一的入口

v2 版本统一走 OTLP。以 Go 应用为例,最小接入代码:

exporter, _ := otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint("localhost:4317"), otlptracegrpc.WithInsecure(), // 本地开发用明文,生产记得换 TLS ) otel.SetTracerProvider(sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter), // 批量导出,减少网络往返 ))

Java、Python、Node.js 用各自的 OpenTelemetry SDK,配置方式相同:把 exporter endpoint 指向localhost:4317(gRPC)或4318(HTTP)。

不想改业务代码?用官方自带的 tracegen 生成模拟流量(--network host让它访问宿主机的 4318 端口):

docker run --rm --network host \ -e OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://localhost:4318/v1/traces" \ jaegertracing/jaeger-tracegen:latest \ -trace-exporter otlp-http -traces 100

验证:先确认数据进来了,再看界面

# 返回的服务列表里应该出现 "tracegen",说明数据已入库 curl -s http://localhost:16686/services

出现结果即代表整条链路跑通了。浏览器打开http://localhost:16686进入 UI。

想要带指标监控的完整演示环境(microsim 微服务模拟器 + OTel Collector + Prometheus + Grafana),可以直接用仓库里现成的 docker-compose/monitor/:

cd docker-compose/monitor docker compose up

(架构图见下图,数据流:应用 SDK → Collector → Jaeger → 存储,UI 同时查 trace 和指标)

Jaeger 监控环境架构:OTel SDK 发出的 trace 经 Collector 分流,trace 进 Jaeger 存储,聚合出的 RED 指标进 Prometheus,最终统一在 UI 呈现

看懂你的第一条追踪数据

打开http://localhost:16686,默认进入查询页。页面分三块:顶部是搜索表单(service、operation、tags、时间窗、是否只看错误),中间是 trace 列表(每条显示总耗时、span 数、服务名、时间),点进单条后是瀑布图详情

Jaeger UI 的 trace 查询界面:上方按服务/操作/标签/时间筛选,列表区展示每条 trace 的总时长与 span 数量,点击某条进入瀑布图

以图中tracegen服务为例,几个关键读法:

  • 总时长(Duration):这条链路从第一个 span 开始到最后一个 span 结束的墙钟时间,比单个 span 耗时更接近用户真实感受
  • 单个 span 的耗时占比:瀑布图里最长的色块就是"关键路径"。如果 9 秒的 trace 里某 span 占了 8 秒,排查就从它开始
  • operation 名:span 的操作名(如GetPOST /api/checkout),同名 operation 的延迟突变往往就是回归点
  • 错误标记:带 ✕ 的 span 表示状态码为错误,搜索表单里可以勾选只看错误 trace

核心能力详解

日常监控看什么:Monitor 标签页的 RED 三件套

v2 内置 SPM(Service Performance Monitoring)功能:jaeger-query 直接从 trace 数据算出调用率(call rate)、错误率(error rate)、延迟分位数(P50/P95/P99),在 UI 的 Monitor 标签页以曲线展示。

Monitor 标签页展示的 RED 指标:请求率、错误率和 P95 延迟按时间分布,可按服务/操作下钻

三个数字高了分别说明什么:

  • P95 延迟上升:大部分请求还正常,但尾部变慢了——通常是某个下游变慢或 GC 抖动,去瀑布图里找变长的 span
  • 错误率上升:配合"只看错误 trace"过滤,定位是哪个 operation 开始报错
  • 请求率与延迟同步跳变:大概率是流量峰值打爆了容量,进入容量规划场景

指标也可以通过 API 直接取,方便接入自己的脚本:

# 查询 tracegen 服务最近 1 小时的 P95 延迟 curl -s "http://localhost:16686/api/metrics/latencies?service=tracegen&quantile=0.95"

排障时查什么:多维过滤 + 依赖图

排障的标准动作是"缩小范围":先按service + 时间窗圈定,再加operationtag(如http.status_code=500)收敛,最后打开具体 trace 看瀑布图。UI 的 Services 页还能看到依赖图,直观回答"谁在调我、我调了谁"。

容量规划看什么:采样策略与存储选型

高流量下全量记录既不现实也没必要,Jaeger 提供三类采样:

方案适合场景注意事项
概率采样(probabilistic)开发/低流量,全量或固定比例无法保证"错误 trace 一条不漏"
自适应采样(adaptive)中流量,v2 默认方向按服务/operation 动态调概率,依赖 trace 反馈
尾部采样(tail_sampling)高流量,只留"有用"的 trace需等待决策窗口(如 5s),占内存

SPM 指标的存储也有两种路线(完整演示见 docker-compose/monitor/ 下的多个 compose 文件):

方案适合场景注意事项
Prometheus 后端已有 Prometheus 生态、要接告警多一个组件,指标有约 60s 聚合延迟
直接查 trace 存储(ES/OS)已经在用 ES/OS 存 trace不引新组件,但查询打到 trace 库
ClickHouse 同时存 trace 和指标数据量大、查询并发高需建表,支持create_schema: true自动建

生产环境怎么配才稳

推荐路径:先 all-in-one 验证 → 数据量上来后换存储、拆组件 → 接入自身监控告警

阶段一:all-in-one + 明确数据上限

内存存储重启即丢,但开发验证够用。关键是显式设上限(参考仓库 cmd/jaeger/config.yaml):

jaeger_storage: backends: some_store: memory: max_traces: 100000 # 只保留最近 10 万条 trace,超了丢最老的,避免内存无界增长

阶段二:数据量上来后换持久化存储

换成 Badger(单机)时,务必设置 TTL,否则磁盘会无限增长(参考 cmd/jaeger/config-badger.yaml):

badger: directories: keys: "/data/jaeger/" values: "/data/jaeger/" ttl: spans: 48h # 只留 48 小时,按排障习惯定;老数据靠归档而非无限保留

换 Elasticsearch/OpenSearch 时,按天滚动索引方便按时间清理(完整配置见 cmd/jaeger/config-elasticsearch.yaml):

elasticsearch: server_urls: ["http://localhost:9200"] indices: index_prefix: "jaeger-main" spans: rollover_frequency: "day" # 每天一个索引,清理就是删旧索引 shards: 5 replicas: 1

阶段三:把 Jaeger 自己也监控起来

v2 默认在8888端口以 Prometheus 格式暴露自身指标(见config.yaml中 telemetry 段)。至少盯这 4 个:

  • otelcol_receiver_accepted_spans:接收到的 span 数,突降说明上游断流
  • otelcol_exporter_sent_spans:成功写入存储的 span 数,与接收数持续差值变大说明存储端在丢
  • traces_span_metrics_calls_total/traces_span_metrics_errors_total:SPM 算出的调用量与错误量,可配业务告警
  • Jaeger 进程的内存与 CPU(容器docker stats或 node exporter)

踩过的坑与诊断路径

数据明明发出去了,UI 里看不到

可能原因:采样策略把流量过滤掉了;endpoint 指错(4317 是 gRPC、4318 是 HTTP,混用会连不上);服务名和你搜索的不一致。

# 1. 先确认后端到底收到了哪些服务 curl -s http://localhost:16686/services # 2. 看 Collector 有没有报错(如 schema/索引问题) docker logs --tail 200 jaeger | grep -iE "error|fail"

调整建议:临时把采样调成全量验证链路;确认应用端OTEL_EXPORTER_OTLP_TRACES_ENDPOINT的协议和端口匹配;搜索时用/services返回的原样服务名。

查询越来越慢

可能原因:时间窗开得太宽(默认 1h 起步,有人直接选"全部");trace 库索引膨胀没清理;单条 trace 的 span 数过多。

# ES 后端:看索引数量和大小,确认滚动索引是否生效、旧索引是否已清 curl -s 'localhost:9200/_cat/indices/jaeger*?s=store.size:desc'

调整建议:养成"先窄时间窗、再放宽"的查询习惯;给旧索引设保留策略;热点查询加 service + operation 条件而不是裸查。

内存 / 磁盘持续增长

可能原因:all-in-one 内存存储接近max_traces上限;Badger/ES 没设 TTL 或滚动;队列积压(消费速度 < 接收速度)。

# 看容器内存水位 docker stats --no-stream # 对比收发差值:sent 明显低于 accepted 说明存储端写入跟不上 curl -s http://localhost:8888/metrics | grep -E "otelcol_(receiver_accepted|exporter_sent)_spans"

调整建议:给 memory 后端设小一点max_traces;给持久化后端设ttl/ 索引保留天数;用tail_sampling或降低概率采样率把入口流量砍下来。

从Demo到生产:进阶玩法

如果你需要"只留慢的和错的,其他全丢":上尾部采样。在 pipeline 里挂tail_samplingprocessor,按属性或延迟过滤(仓库里有现成示例cmd/jaeger/config-tail-sampling-service-name-policy.yaml):

processors: tail_sampling: decision_wait: 5s # 等 5 秒攒齐一条 trace 再决策 policies: - name: keep-tracegen type: string_attribute string_attribute: { key: service.name, values: [tracegen-00] }

如果你需要按业务维度下钻:在应用里给 span 加自定义属性(如business.tier=premium),UI 搜索表单的 tags 里就能直接按business.tier=premium过滤——这是把追踪从"技术视角"扩展到"业务视角"的关键一步。

如果你需要回答"这次发布动了哪些依赖":对比发布前后的 Services 依赖图和 Monitor 页 RED 曲线,比翻变更日志快得多。

收尾:你的行动清单

  • docker run拉起 all-in-one,curl http://localhost:16686/services返回tracegen
  • 用 OTLP 把一个真实应用接进来(gRPC 4317 或 HTTP 4318),在 UI 看到第一条自己的 trace
  • 按流量规模选定采样策略:概率 / 自适应 / 尾部采样,写进配置
  • 存储从 memory 换到 Badger 或 ES/ClickHouse,并显式设置 TTL / 索引保留
  • 8888端口的自身指标接入 Prometheus,至少对 span 接收/写出差值配一条告警

从 Demo 到生产不是一次切换,而是"数据量倒逼"的渐进过程:先保证链路可见,再谈留存和告警。

核心关键词:Jaeger分布式追踪, 分布式追踪平台, 微服务性能监控, OpenTelemetry OTLP接入, Jaeger生产部署 长尾关键词:Jaeger all-in-one一键启动, Jaeger采样策略配置, Jaeger存储后端选择, Jaeger SPM服务性能监控, Jaeger故障诊断排查指南

【免费下载链接】jaegerCNCF Jaeger, a Distributed Tracing Platform项目地址: https://gitcode.com/GitHub_Trending/ja/jaeger

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询