Jaeger 中文教程
1. 项目概述
Jaeger 是一个开源的分布式追踪系统,由 Uber 开发并捐赠给 Cloud Native Computing Foundation (CNCF)。它专为监控和排查微服务架构中的性能问题而设计,提供了分布式事务的追踪、性能监控和故障排查能力。
主要功能
- 分布式事务追踪:跟踪请求在微服务架构中的完整调用链
- 性能监控:识别系统瓶颈和性能问题
- 服务依赖分析:可视化服务间的调用关系
- 根因分析:快速定位故障源头
- 多维度数据:支持按服务、操作、标签等多维度分析
- 实时数据:提供近实时的追踪数据
- 历史数据:支持存储和查询历史追踪数据
- 告警集成:与 Prometheus 等告警系统集成
技术栈特点
- 用 Go 语言编写,性能优异
- 基于 OpenTelemetry 和 OpenTracing 标准
- 支持多种存储后端:Cassandra、Elasticsearch、Kafka
- 水平可扩展:支持集群部署
- 与 Kubernetes 深度集成
适用环境
- 微服务架构
- 分布式系统
- 云原生环境
- 容器化应用
2. 安装与配置
2.1 全-in-One 安装(开发环境)
使用 Docker 运行全-in-One 模式的 Jaeger:
docker run -d \n --name jaeger \n -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \n -p 5775:5775/udp \n -p 6831:6831/udp \n -p 6832:6832/udp \n -p 5778:5778 \n -p 16686:16686 \n -p 14268:14268 \n -p 14250:14250 \n -p 9411:9411 \n jaegertracing/all-in-one:1.352.2 生产环境安装
2.2.1 使用 Helm 安装到 Kubernetes
helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm repo update
helm install jaeger jaegertracing/jaeger2.2.2 分布式部署
生产环境中,Jaeger 通常采用分布式部署,包括以下组件:
- Jaeger Collector:接收和处理追踪数据
- Jaeger Query:提供查询和 UI 服务
- Jaeger Agent:部署在每个主机上,接收本地追踪数据并批量发送给 Collector
- 存储后端:如 Elasticsearch 或 Cassandra
2.3 基本配置
2.3.1 Collector 配置
# collector-config.yaml
receivers:
jaeger:
protocols:
grpc:
thrift_binary:
thrift_compact:
thrift_http:
zipkin:
exporters:
jaeger:
endpoint: jaeger-all-in-one:14250
tls:
insecure: true
logging:
processors:
batch:
queued_retry:
exporter_type: "jaeger-thrift-http"
storage:
type: elasticsearch
options:
es:
servers: http://elasticsearch:9200
username: elastic
password: changeme
index-prefix: jaeger-
disable-tls: true2.3.2 Agent 配置
# agent-config.yaml
reporters:
jaeger:
protocol: grpc
endpoint: collector:14250
tls:
insecure: true
sampling:
strategies:
default_strategy:
type: probabilistic
param: 0.13. 基本使用
3.1 启动 Jaeger
# 启动全-in-One 模式
docker run -d --name jaeger -p 16686:16686 jaegertracing/all-in-one:1.35
# 访问 Jaeger UI
# 打开浏览器访问 http://localhost:166863.2 访问 Jaeger UI
Jaeger 启动后,可以通过 http://localhost:16686 访问 Jaeger UI。
3.3 集成应用
3.3.1 Node.js 应用集成
使用 OpenTelemetry 集成 Node.js 应用:
# 安装依赖
npm install @opentelemetry/sdk-node @opentelemetry/exporter-jaeger @opentelemetry/instrumentation-express @opentelemetry/instrumentation-http// tracing.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
const { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const sdk = new NodeSDK({
traceExporter: new JaegerExporter({
endpoint: 'http://localhost:14268/api/traces'
}),
instrumentations: [
new HttpInstrumentation(),
new ExpressInstrumentation()
],
serviceName: 'my-service'
});
sdk.start();// app.js
require('./tracing');
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server listening on port 3000');
});3.3.2 其他语言集成
- Java:使用 OpenTelemetry Java SDK 或 Jaeger Java Client
- Python:使用 OpenTelemetry Python SDK 或 Jaeger Python Client
- Go:使用 OpenTelemetry Go SDK 或 Jaeger Go Client
- .NET:使用 OpenTelemetry .NET SDK 或 Jaeger .NET Client
3.4 查看追踪数据
- 访问 Jaeger UI:http://localhost:16686
- 在 "Service" 下拉菜单中选择服务名称
- 在 "Operation" 下拉菜单中选择操作名称
- 点击 "Find Traces" 按钮
- 查看追踪结果列表
- 点击单个追踪查看详细信息
3.5 基本查询
Jaeger UI 支持以下查询方式:
- 按服务和操作查询:选择服务和操作名称
- 按时间范围查询:设置开始和结束时间
- 按标签查询:使用标签键值对过滤
- 按追踪 ID 查询:直接输入追踪 ID
4. 高级特性
4.1 采样策略
Jaeger 支持多种采样策略:
- Probabilistic(概率采样):按固定概率采样
- Rate Limiting(速率限制):限制每秒采样数量
- Remote(远程采样):从 Collector 获取采样策略
- Per Operation(按操作采样):为不同操作设置不同采样策略
4.1.1 配置采样策略
# sampling-strategies.json
{
"service_strategies": [
{
"service": "my-service",
"type": "probabilistic",
"param": 0.5,
"operation_strategies": [
{
"operation": "GET /api/users",
"type": "probabilistic",
"param": 0.1
}
]
}
],
"default_strategy": {
"type": "probabilistic",
"param": 0.01
}
}4.2 分布式上下文传播
Jaeger 使用 OpenTelemetry 或 OpenTracing 标准进行上下文传播,支持以下协议:
- Jaeger gRPC:基于 gRPC 的二进制协议
- Jaeger Thrift:基于 Thrift 的二进制协议
- Zipkin:兼容 Zipkin 协议
- W3C Trace Context:W3C 标准的追踪上下文格式
4.3 定制化追踪
4.3.1 手动创建跨度
Node.js 示例:
const { trace } = require('@opentelemetry/api');
// 获取当前追踪器
const tracer = trace.getTracer('my-service');
// 创建新跨度
const span = tracer.startSpan('process-order');
// 设置标签
span.setAttribute('order.id', '12345');
span.setAttribute('user.id', '67890');
// 执行操作
try {
await processOrder('12345');
span.setStatus({ code: 0 }); // OK
} catch (error) {
span.setStatus({ code: 2, message: error.message }); // ERROR
span.recordException(error);
} finally {
// 结束跨度
span.end();
}4.3.2 创建子跨度
const parentSpan = trace.getSpan(context.active());
const childSpan = tracer.startSpan('validate-order', {
parent: parentSpan,
attributes: {
'order.amount': 100.00
}
});
// 执行子操作
await validateOrder('12345');
// 结束子跨度
childSpan.end();4.4 与 Prometheus 集成
Jaeger 可以与 Prometheus 集成,实现基于追踪数据的告警:
- 启用 Jaeger 的 Prometheus 指标
- 配置 Prometheus 抓取 Jaeger 指标
- 创建基于追踪数据的告警规则
# prometheus-alerts.yaml
groups:
- name: jaeger-alerts
rules:
- alert: HighTraceErrorRate
expr: |
sum(rate(jaeger_collector_spans_total{status="error"}[5m])) by (service_name) / sum(rate(jaeger_collector_spans_total[5m])) by (service_name) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate in traces"
description: "Service {{ $labels.service_name }} has error rate of {{ $value }} in traces"
- alert: SlowTraceDuration
expr: |
histogram_quantile(0.95, sum(rate(jaeger_collector_span_duration_seconds_bucket[5m])) by (service_name, operation_name, le)) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "Slow trace duration"
description: "Operation {{ $labels.operation_name }} in service {{ $labels.service_name }} has 95th percentile duration of {{ $value }} seconds"4.5 性能优化
4.5.1 存储优化
- 使用适当的存储后端:生产环境推荐使用 Elasticsearch 或 Cassandra
- 配置索引生命周期:设置适当的索引保留时间
- 调整批量大小:优化 Collector 的批量处理大小
- 使用采样:合理配置采样策略,减少存储压力
4.5.2 Collector 优化
- 水平扩展:部署多个 Collector 实例
- 使用队列:配置适当的队列大小和重试策略
- 优化批处理:调整批处理大小和间隔
4.5.3 Agent 优化
- 部署在每个主机:减少网络开销
- 批量发送:配置适当的批处理大小
- 压缩数据:启用数据压缩
5. 最佳实践
5.1 追踪设计
- 为每个服务设置有意义的名称:便于在 Jaeger UI 中识别
- 为每个操作设置有意义的名称:如 HTTP 方法 + 路径
- 添加有意义的标签:如用户 ID、订单 ID、错误类型等
- 保持跨度粒度适当:不要创建过多或过少的跨度
- 记录关键事件:如数据库查询、外部 API 调用、业务逻辑决策
5.2 集成策略
- 使用自动化 instrumentation:优先使用自动 instrumentation 库
- 补充手动 instrumentation:对关键业务逻辑添加手动追踪
- 标准化上下文传播:确保所有服务使用相同的上下文传播机制
- 统一采样策略:在整个系统中使用一致的采样策略
5.3 数据管理
- 设置合理的保留期:根据业务需求和存储成本设置
- 使用索引模板:为 Elasticsearch 设置适当的索引模板
- 监控存储使用:定期监控存储使用情况
- 备份重要数据:对重要的追踪数据进行备份
5.4 告警策略
- 基于关键指标:如错误率、P95 响应时间
- 设置合理的阈值:避免误报
- 分级告警:根据严重程度设置不同级别的告警
- 与其他监控系统集成:如 Prometheus、Grafana
5.5 安全最佳实践
- 保护 Jaeger UI:添加认证和授权
- 加密传输:使用 TLS 加密数据传输
- 限制访问:只允许必要的人员访问 Jaeger
- 敏感数据处理:避免在追踪中存储敏感信息
6. 实际应用场景
6.1 微服务架构监控
使用 Jaeger 监控微服务架构的完整调用链:
场景:一个电商系统,包含用户服务、订单服务、支付服务、库存服务等多个微服务。
追踪流程:
- 用户请求
POST /api/orders创建订单 - 订单服务调用用户服务验证用户信息
- 订单服务调用库存服务检查库存
- 订单服务调用支付服务处理支付
- 订单服务更新订单状态
- 订单服务返回响应给用户
查询与分析:
- 查看完整调用链:在 Jaeger UI 中通过追踪 ID 查看完整的调用链
- 识别瓶颈:查看每个服务的响应时间,识别性能瓶颈
- 分析依赖关系:通过服务依赖图分析服务间的依赖关系
- 排查错误:当出现错误时,通过追踪数据快速定位错误源头
6.2 性能问题排查
使用 Jaeger 排查系统性能问题:
场景:系统响应时间突然增加,需要快速定位原因。
排查步骤:
- 在 Jaeger UI 中查询最近的追踪数据
- 按响应时间排序,找到最慢的请求
- 查看慢请求的详细调用链
- 分析每个服务的响应时间,识别瓶颈服务
- 查看瓶颈服务的内部操作,定位具体问题
- 实施优化措施
- 验证优化效果
6.3 服务依赖分析
使用 Jaeger 分析服务间的依赖关系:
场景:需要了解系统中服务间的调用关系,优化系统架构。
分析步骤:
- 在 Jaeger UI 中点击 "Dependencies" 标签
- 查看服务依赖图,了解服务间的调用关系
- 分析依赖图,识别:
- 强依赖服务
- 循环依赖
- 过度依赖的服务
- 未使用的服务
- 根据分析结果优化系统架构
6.4 多环境对比
使用 Jaeger 对比不同环境的性能:
场景:需要对比开发、测试、生产环境的性能差异。
对比步骤:
- 在不同环境部署相同的 Jaeger 配置
- 执行相同的测试场景
- 在 Jaeger UI 中查询并导出追踪数据
- 对比不同环境的:
- 响应时间分布
- 错误率
- 服务调用次数
- 资源使用情况
- 分析差异原因,优化环境配置
7. 总结
Jaeger 是一个功能强大、性能优异的分布式追踪系统,它为微服务架构和分布式系统提供了全面的可观测性解决方案。通过本文的介绍,您应该已经了解了 Jaeger 的核心概念、安装配置、基本使用和高级特性。
关键优势
- 开源免费:作为 CNCF 项目,完全开源免费
- 标准兼容:支持 OpenTelemetry 和 OpenTracing 标准
- 性能优异:用 Go 语言编写,性能出色
- 可扩展性:支持水平扩展,适合大型系统
- 生态丰富:与 Prometheus、Grafana 等工具无缝集成
- 易于使用:提供直观的 UI 和丰富的查询功能
应用场景
- 微服务架构监控和故障排查
- 分布式系统性能分析
- 服务依赖关系分析
- 多环境性能对比
- DevOps 持续监控
Jaeger 与 Prometheus、Grafana 等工具结合使用,可以构建完整的可观测性平台,帮助您更好地理解和优化系统性能,提高系统的可靠性和可用性。