Jaeger + OpenTelemetry:云原生可观测性

FreeGuideOnline 最新 2026-06-30

Jaeger 与 OpenTelemetry:构建云原生可观测性的标准组合

在现代分布式系统中,理解请求的完整生命周期、快速定位性能瓶颈和故障根源已成为刚需。JaegerOpenTelemetry 正是这一领域的两大核心项目:前者是久经考验的分布式追踪后端与可视化工具,后者是 CNCF 托管的可观测性数据采集与传输标准。将二者结合,你能用一套统一、无厂商锁定的方式采集链路、指标和日志,并利用 Jaeger 强大的分析能力洞悉系统行为。本教程将手把手带你理解并实践这一组合。


1. 为什么我们需要 OpenTelemetry 和 Jaeger?

现代应用由数十甚至数百个微服务组成,一次用户点击可能触发数十次 RPC 调用。传统日志和监控很难回答“这次请求到底在哪里慢了”或“错误是从哪个服务开始发散的”。分布式追踪通过一次请求的全链路 trace 将分散的事件串联起来,而 OpenTelemetry (OTel) 解决了多语言、多协议数据采集的标准化问题,Jaeger 则针对这些数据提供了高性能的存储、检索和可视化能力。

核心价值:

  • 端到端可见性:从边缘网关到数据库查询,完整的调用链清晰呈现。
  • 统一采集标准:使用 OTel 的 API/SDK 生成追踪、指标、日志,数据格式与导出工具解耦。
  • 灵活的后端切换:今天使用 Jaeger,明天可以无缝迁移到其他支持 OTLP 的后端,无需修改应用代码。
  • 原生云原生:两者均为 CNCF 项目,与 Kubernetes、服务网格(如 Istio)深度集成。

2. 认识关键角色

2.1 OpenTelemetry:数据管道的通用接口

OpenTelemetry 是一组 API、SDK、收集器和工具,用于创建和管理遥测数据。它不负责存储和展示,而是专注于:

  • 生成:应用通过 OTel SDK 创建 span、metric 等。
  • 处理/采样:可在收集器层面对数据进行批处理、过滤、尾部采样。
  • 导出:通过 OTLP 协议将数据发送到你选择的后端。

三大信号(Signals):

  1. Traces(追踪):描述一次请求在分布式系统中的行进路径。
  2. Metrics(指标):聚合的测量值,如请求速率、错误率、延迟分位数。
  3. Logs(日志):带时间戳的事件记录,可与 trace 关联。

2.2 Jaeger:分布式追踪的专家

Jaeger 最初由 Uber 开发,专为分布式上下文传播、性能分析和根因判断而设计。它的关键能力包括:

  • 接收器:原生支持多种协议(Thrift, OTLP, Zipkin 等)。
  • 存储后端:可对接 Elasticsearch、Cassandra、内存等,支持高基数查询。
  • 全链路视图:甘特图式的 trace 时间轴,展示每个服务耗时的父子关系。
  • 依赖分析:自动推导服务间调用拓扑。
  • 自适应采样:根据策略决定保留哪些 trace,平衡成本与覆盖率。

3. 架构总览:如何协同工作

典型的部署架构如下:

┌─────────────┐     OTLP      ┌─────────────────┐      OTLP/Thrift      ┌─────────┐
│  服务 A     │  ──────────→  │ OpenTelemetry   │  ─────────────────→   │ Jaeger  │
│ (OTel SDK)  │               │    Collector     │                       │ 后端    │
└─────────────┘               └─────────────────┘                       └─────────┘
      ▲                              ▲                                      │
      │              可选:处理/采样/富化                                     │
      │                                                                      ↓
┌─────────────┐                                                      存储 + 查询 UI
│  服务 B     │
│ (OTel SDK)  │
└─────────────┘
  1. 仪表化(Instrumentation):各服务使用 OTel SDK(或自动仪表化)生成 span,并将 span 上下文通过 HTTP/gRPC 等自动传播。
  2. 导出到收集器:每个服务可将遥测数据直接通过 OTLP 发送到 Jaeger,但推荐经过 OpenTelemetry Collector。收集器可部署为网关或 Sidecar,负责接收、批处理、过滤、执行尾部采样,然后统一转发到 Jaeger。
  3. Jaeger 存储与展示:Jaeger 接收并存储 span,提供简洁的 UI 进行查询和分析。

4. 动手实践:从零搭建完整示例

我们将用 Docker Compose 快速拉起一个包含 Jaeger、OpenTelemetry Collector 和示例应用的演示环境。

4.1 准备基础设施

创建 docker-compose.yaml

version: "3.9"
services:
  # Jaeger 一体式镜像,包含 agent、collector、query、UI
  jaeger:
    image: jaegertracing/all-in-one:1.58
    container_name: jaeger
    ports:
      - "16686:16686"   # UI
      - "4317:4317"     # OTLP gRPC
      - "4318:4318"     # OTLP HTTP
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    restart: unless-stopped

  # OpenTelemetry Collector 示例
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.102.0
    container_name: otel-collector
    command: ["--config=/etc/otel-collector-config.yaml"]
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
    ports:
      - "1888:1888"   # 可选的 pprof 扩展
    depends_on:
      - jaeger

然后在同目录下创建 otel-collector-config.yaml

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  otlp/jaeger:
    endpoint: jaeger:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/jaeger]

启动环境:

docker compose up -d

此时 Jaeger UI 可通过 http://localhost:16686 访问。

4.2 为应用添加 OpenTelemetry 追踪

以 Python 为例,使用自动仪表化最快上手。假设你有一个简单的 Flask 服务。

安装依赖:

pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install

配置导出器(环境变量):

export OTEL_SERVICE_NAME=order-service
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true

启动应用并自动注入仪表化:

opentelemetry-instrument python app.py

对于 Java、Go、.NET 等也都有类似的自动仪表化方案。现在所有请求产生的 span 都会通过 OTLP 发送到 OpenTelemetry Collector,进而转发至 Jaeger。

4.3 在 Jaeger UI 中分析追踪

访问 http://localhost:16686,你将看到服务列表中出现了 order-service。点击 “Find Traces” 即可看到最近的请求 trace。

  • Trace 概览:显示总耗时、涉及的服务数量、span 数量。
  • 时间瀑布图:每个 span 的父子关系以甘特图呈现,鼠标悬停可查看详细属性(标签、日志事件)。
  • 关键分析:点击某个慢 span 可查看其内的自定义属性,例如数据库查询语句、RPC 方法名。

5. 关键配置与最佳实践

5.1 上下文传播

确保所有服务都使用 W3C TraceContext 作为传播格式,这是 OTel 的默认方式,可实现跨语言、跨协议的兼容。如果你有旧系统使用 Zipkin 或 Jaeger 原生传播头,可在 SDK 或收集器层面配置兼容。

5.2 采样策略

并非所有 trace 都需要保留,合理采样可大幅降低存储成本。

  • 头部采样(Head Sampling):在 span 创建时决定,例如只保留5%的请求,随机采样或基于规则(如错误请求全保留)。可在 OTel SDK 中配置。
  • 尾部采样(Tail Sampling):在 trace 完整后再决策,保留包含错误、长延迟的完整链路。必须在 OpenTelemetry Collector 中配置,因为只有收集器能看到完整链路。Jaeger 自己也支持远程采样策略,可将策略集中管理。

Tail Sampling 配置片段(在 collector 中):

processors:
  tail_sampling:
    decision_wait: 10s
    policies:
      - name: error-policy
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: latency-policy
        type: latency
        latency: { threshold_ms: 500 }

5.3 丰富 span 信息

利用 OTel SDK 添加自定义属性,将业务上下文注入:

from opentelemetry import trace
current_span = trace.get_current_span()
current_span.set_attribute("user.id", "12345")
current_span.set_attribute("order.amount", 99.9)

这些属性会出现在 Jaeger UI 的 span 详情中,极大提升排查效率。

5.4 日志与 trace 关联

将日志关联到对应的 trace 和 span,实现从日志跳转到 trace 的能力。在结构化日志中注入 trace_idspan_id,例如在Java中使用MDC:

import io.opentelemetry.api.trace.Span;
Span.current().getSpanContext().getTraceId();

Jaeger UI 支持在 span 的 “Logs” 面板中查看关联的事件。

5.5 监控 Jaeger 自身

关注 Jaeger 组件的健康度,使用 Prometheus 采集 Jaeger 的 metrics(由 SPAN_STORAGE_TYPE 等配置暴露),配合 Grafana 仪表盘。OpenTelemetry Collector 也应导出自身遥测数据到监控系统。


6. 常见问题与故障排除

问题现象 可能原因 解决方案
UI 中看不到服务 OTLP 端点不通或服务名称未设置 检查 OTEL_EXPORTER_OTLP_ENDPOINT 是否正确,确认 Jaeger 是否启用了 OTLP receiver (--collector.otlp.enabled=true)
Span 不完整或缺失 采样丢弃、传播头丢失 检查采样率;确认服务间请求头传递 W3C traceparent
Jaeger 内存飙升 内存存储模式下 trace 过多 设置 SPAN_STORAGE_TYPE=badger 并限制保留时长,或切换至 Elasticsearch
收集器报错 “connection refused” Jaeger 尚未就绪或地址错误 确保收集器配置中的 Jaeger endpoint 容器名正确(如 jaeger:4317

7. 进阶方向

  • Kubernetes 原生集成:使用 OpenTelemetry Operator 自动注入 sidecar 或自动仪表化,搭配 Jaeger Operator 在集群内全托管。
  • 服务网格配合:Istio 的分布式追踪默认使用 Zipkin 协议,可配置 MeshConfig 将 traces 直接发送至 Jaeger,或通过 OpenTelemetry Collector 作为统一入口。
  • 指标与告警:将 OTel 生成的指标导出至 Prometheus,使用 Jaeger 的 latency 数据配置 Prometheus 告警规则。
  • 多租户与身份认证:为 Jaeger Query 添加 OAuth 代理或 JWT 认证,按 team 隔离 trace 访问。

总结

Jaeger 与 OpenTelemetry 的融合并非简单的“发送-接收”关系,而是一个精心设计的可观测性管道:OpenTelemetry 负责统一生成与路由遥测信号,Jaeger 作为专业的追踪后端提供深度分析与可视化。这种组合已成为云原生观测的事实标准,既能帮助你轻松起步,又能在系统规模增长时提供足够的灵活性与韧性。立即开始为你的服务添加一行 opentelemetry-instrument,让复杂的调用链从此透明。