什么是 Jaeger?

Jaeger 是一个分布式追踪系统,主要用于监控和故障排查分布式系统中的微服务架构。它帮助开发者跟踪请求在多个微服务中的路径,发现系统瓶颈,并分析各个服务之间的延迟和依赖关系。Jaeger 最早由 Uber 开发,现在已经成为 CNCF (Cloud Native Computing Foundation) 的孵化项目之一。

Jaeger 的作用

  • 分布式追踪:追踪请求从一个服务传递到另一个服务的路径,提供可视化的请求流。
  • 性能监控:检测每个微服务的性能瓶颈,分析延迟,帮助优化系统。
  • 故障排查:在复杂系统中快速定位错误发生的服务或阶段。
  • 依赖关系分析:显示服务之间的调用链,帮助开发者理解系统架构。

Jaeger 的核心概念

  1. Trace (追踪)

    • 代表一个请求的整个生命周期,从进入系统的第一个服务到流经不同服务的整个过程。
    • 每个 Trace 包含多个 Span
  2. Span (跨度)

    • SpanTrace 中的一个单独的操作,例如一个 HTTP 请求、数据库查询、远程调用等。
    • 每个 Span 包括开始时间、持续时间、操作名称、标签、日志等信息。
  3. Context (上下文)

    • 上下文用于跨服务传递追踪信息,通常通过 HTTP headers 或 RPC 的元数据中传递。
  4. Parent-Child 关系

    • 一个请求可能会经过多个微服务,每个服务的 Span 可以有父子关系,形成完整的调用链。

Jaeger 的工作原理

Jaeger 使用了分布式追踪的四步流程

  1. Instrumentation (插桩)

    • 在微服务中添加追踪代码,使服务在处理请求时能够生成 Span 并记录追踪数据。通过开源的追踪库(如 OpenTelemetry 或 OpenTracing)来插桩,自动生成追踪信息。
  2. Collection (收集)

    • Jaeger 会将生成的 Span 数据发送到 Jaeger 后端系统。后端系统负责收集所有 Span 并组装成完整的 Trace
  3. Storage (存储)

    • Jaeger 支持多种存储后端,包括 Elasticsearch、Cassandra、Kafka 等,用于持久化存储追踪数据。
  4. Visualization (可视化)

    • 用户可以通过 Jaeger UI 查看、分析追踪数据,定位性能瓶颈和错误位置。

Jaeger 的架构

Jaeger 典型架构包括以下组件:

  • Agent:运行在每个服务节点上,负责将追踪数据发送到 Jaeger Collector。
  • Collector:接收来自 Agent 的追踪数据并存储。
  • Query Service:用户可以通过这个服务查询追踪数据,并通过 UI 展示。
  • Storage Backend:存储追踪数据,支持 Cassandra、Elasticsearch 等。

如何学习使用 Jaeger

1. 安装 Jaeger

最简单的方式是通过 Docker 启动 Jaeger。首先,确保你已安装 Docker,然后运行以下命令来启动 Jaeger:

docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 14250:14250 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.22
  • 访问 Jaeger UI:http://localhost:16686
2. 在微服务中引入 Jaeger

通过 OpenTelemetry 或 OpenTracing 库在你的微服务代码中集成 Jaeger 追踪。下面是一个 Spring Boot 应用集成 Jaeger 的例子:

示例 1:使用 OpenTelemetry 集成 Jaeger

步骤 1:添加依赖

pom.xml 中添加 OpenTelemetry 和 Jaeger 的依赖:

<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-jaeger</artifactId>
    <version>1.5.0</version>
</dependency>

步骤 2:配置 Jaeger 导出器

在应用的 application.properties 中配置 Jaeger:

otel.exporter.jaeger.endpoint=http://localhost:14250
otel.exporter.jaeger.service.name=my-service

步骤 3:编写代码

在代码中初始化 OpenTelemetry 并生成 Span

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;

@RestController
public class MyController {

    private static final Tracer tracer = GlobalOpenTelemetry.getTracer("example-tracer");

    @GetMapping("/hello")
    public String sayHello() {
        Span span = tracer.spanBuilder("sayHello-span").startSpan();
        span.addEvent("Saying hello");
        
        try {
            return "Hello, Jaeger!";
        } finally {
            span.end();
        }
    }
}

当你访问 /hello 端点时,Jaeger 会捕获到 sayHello-span 这个 Span,并且你可以在 Jaeger UI 中查看到追踪信息。

3. 分布式追踪的实际使用场景

假设一个电子商务系统中有三个微服务:

  • 订单服务:接收用户订单。
  • 支付服务:处理用户支付。
  • 发货服务:安排订单发货。

在系统中,一个请求可能从订单服务开始,依次传递到支付服务和发货服务。Jaeger 可以帮助我们跟踪这个请求在不同服务中的执行情况,生成以下调用链:

User -> [Order Service] -> [Payment Service] -> [Shipment Service]

通过 Jaeger,你可以在每个微服务中看到请求的执行时间和延迟情况,如果某个服务有性能瓶颈,可以快速定位。

示例 2:分布式追踪的实际使用

服务 A:订单服务
// OrderService.java
public void placeOrder(Order order) {
    Span span = tracer.spanBuilder("placeOrder").startSpan();
    try {
        // 处理订单
        paymentService.processPayment(order);
        shipmentService.scheduleShipment(order);
    } finally {
        span.end();
    }
}
服务 B:支付服务
// PaymentService.java
public void processPayment(Order order) {
    Span span = tracer.spanBuilder("processPayment").startSpan();
    try {
        // 模拟支付处理
    } finally {
        span.end();
    }
}
服务 C:发货服务
// ShipmentService.java
public void scheduleShipment(Order order) {
    Span span = tracer.spanBuilder("scheduleShipment").startSpan();
    try {
        // 模拟发货安排
    } finally {
        span.end();
    }
}

在 Jaeger UI 中,你可以看到一个完整的调用链,从订单服务到支付服务,再到发货服务。每个 Span 都会展示执行的时间,帮助你分析系统的性能和潜在的瓶颈。

结论

Jaeger 是强大的分布式追踪工具,帮助开发者跟踪和优化微服务架构中的请求流。通过简单的插桩,我们可以轻松获取每个请求的详细追踪数据,并在 Jaeger UI 中分析系统的性能和依赖关系。通过逐步学习如何集成 Jaeger 和使用分布式追踪,可以显著提高系统的可观测性和故障排查能力。

Logo

更多推荐