当前位置: 首页 > news >正文

分布式追踪系统Jaeger

什么是 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 和使用分布式追踪,可以显著提高系统的可观测性和故障排查能力。


http://www.mrgr.cn/news/54078.html

相关文章:

  • Centos7源报错问题
  • HCIE-Datacom题库_13_认证多选、判断、简答【13道题】
  • 微服务的一些基本概念
  • 详解Shell脚本与Ansible自动化工具差异
  • 常用的网络配置命令
  • Flink窗口分配器WindowAssigner
  • Bootstrapping、Bagging 和 Boosting
  • ●day 35 动态规划part01
  • MySQL知识点_03
  • LeetCode 2379.得到K个黑块的最少涂色次数
  • springboot036海滨体育馆管理系统的设计与实现(论文+源码)_kaic
  • 【进阶OpenCV】 (20) --疲劳检测
  • 6-2.Android 对话框之基础对话框问题清单(UI 线程问题、外部取消、冲突问题、dismiss 方法与 hide 方法)
  • 数据结构之单链表
  • 2063:【例1.4】牛吃牧草
  • CSDN Markdown 编辑器语法大全
  • 商​汤​二​面
  • 餐饮店怎么标注地图位置信息?
  • 2062:【例1.3】电影票
  • 48.旋转图像
  • FloodFill 算法(DFS)
  • [C++] C++类和对象 类的初始化列表和静态成员 类型转换/友元/内部类/匿名对象/编译器优化
  • Symbol简单介绍
  • 【电子通识】案例:两个按键同时按下把boot拉低电路如何设计?
  • VIT:论文关键点解读与常见疑问
  • mac安装jdk8