基于OpenTelemetry实现分布式链路追踪

基于OpenTelemetry实现分布式链路追踪

文章目录

在微服务架构普及的当下,一个用户请求往往会经过多个服务节点的协同处理,一旦出现接口超时、报错等问题,仅凭日志定位根因变得异常困难。分布式链路追踪作为可观测性三大核心能力(日志、指标、追踪)之一,能清晰还原请求的全链路路径、各环节耗时及异常信息,是保障分布式系统稳定运行的关键工具。本文将详细介绍如何基于 OpenTelemetry(简称 OTel)结合 Jaeger,快速搭建一套轻量、易用的分布式链路追踪系统,并完成 Java 服务的链路接入。

本方案在为链路追踪入门实践。

一、方案整体介绍

核心组件说明

OpenTelemetry:统一的可观测性采集框架

OpenTelemetry 是 CNCF 孵化的开源可观测性框架,核心目标是统一分布式追踪、指标、日志的采集标准,解决不同厂商 / 工具采集格式不兼容的问题。其核心组件包括:

  • SDK/Agent:多语言埋点能力,支持自动埋点(如 Java Agent 无需修改业务代码)和手动埋点,负责生成追踪数据(Trace/Span);
  • Collector:数据处理中间件,提供数据接收、过滤、转换、转发能力,解耦采集端和存储端,支持对接多种后端(Jaeger、Prometheus、Elasticsearch 等);
  • Exporter:数据导出组件,将采集的可观测数据发送到指定后端。

OpenTelemetry 的优势在于无厂商锁定、生态丰富,能适配绝大多数微服务技术栈,是当前分布式追踪采集层的主流选择。

Jaeger:轻量的追踪数据存储与可视化工具

Jaeger 是 Uber 开源的分布式追踪系统,专注于追踪数据的存储、查询和可视化,提供开箱即用的 All-in-One 部署模式,适合中小规模场景快速落地。其核心能力包括:

  • 接收 OpenTelemetry、Zipkin 等标准格式的追踪数据;
  • 提供可视化 UI,支持按服务、操作、时间范围筛选链路,查看 Span 耗时、调用关系;
  • 支持分布式上下文传播,还原跨服务调用链路。

方案架构设计

本方案采用 "Agent 采集 + Collector 转发 + Jaeger 存储 / 可视化" 的经典架构,整体流程如下:

  1. 业务 Java 服务通过 OpenTelemetry Java Agent 实现无侵入自动埋点,生成追踪数据;
  2. 追踪数据通过 OTLP(OpenTelemetry Protocol)协议发送到 OTel Collector;
  3. OTel Collector 对数据进行批处理优化后,转发至 Jaeger 后端;
  4. 运维 / 开发人员通过 Jaeger UI 查看全链路追踪信息,定位问题。
  5. 仅仅作为在测试环境内使用,若上线生产则需增加认证以及ES存储。

二、环境准备

1、镜像准备

为提升镜像拉取速度,本文使用华为云镜像源拉取 OTel Collector 和 Jaeger 镜像,拉取后统一打标为官方标签,避免后续部署命令修改:

bash 复制代码
# 拉取镜像
root@uat:/data/otel#  docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/otel/opentelemetry-collector-contrib:latest
root@uat:/data/otel#  docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jaegertracing/all-in-one:latest 

# 镜像标签
root@uat:/data/otel#  docker tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jaegertracing/all-in-one:latest  docker.io/jaegertracing/all-in-one:latest 
root@uat:/data/otel#  docker tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/otel/opentelemetry-collector-contrib:latest  docker.io/otel/opentelemetry-collector-contrib:latest 

2、端口准备

分布式追踪系统需占用多个端口,需提前检查是否被占用,各端口用途如下:

端口 协议 用途 所属组件
5775 UDP Jaeger 经典协议接收端口 Jaeger
6831 UDP Jaeger Thrift 协议端口 Jaeger
6832 UDP Jaeger Thrift 协议端口 Jaeger
16686 TCP Jaeger UI 访问端口 Jaeger
4317 TCP OTLP gRPC 协议接收端口 OTel Collector/Jaeger
4318 TCP OTLP HTTP 协议接收端口 OTel Collector/Jaeger
14250 TCP Jaeger gRPC 协议端口 Jaeger

执行以下命令检查 TCP/UDP 端口占用情况:

bash 复制代码
root@uat:/data/projects/easewise/easewise-back# PORTS="5775 6831 6832 16686 14250 4317 4318" 
for port in $PORTS; do
  ss -tuln | grep -E ":$port\b" > /dev/null
  if [ $? -eq 0 ]; then
    echo "⚠️  TCP端口 $port 已被占用:$(ss -tuln | grep -E ":$port\b")"
  else
    echo "✅  TCP端口 $port 未被占用"
  fi
done
✅  TCP端口 5775 未被占用
✅  TCP端口 6831 未被占用
✅  TCP端口 6832 未被占用
✅  TCP端口 16686 未被占用
✅  TCP端口 14250 未被占用
✅  TCP端口 4317 未被占用
✅  TCP端口 4318 未被占用
root@uat:/data/projects/easewise/easewise-back# UDP_PORTS="5775 6831 6832"
root@uat:/data/projects/easewise/easewise-back# for port in $UDP_PORTS; do
  ss -tuln | grep -E ":$port\b" > /dev/null
  if [ $? -eq 0 ]; then
    echo "⚠️  UDP端口 $port 已被占用:$(ss -tuln | grep -E ":$port\b")"
  else
    echo "✅  UDP端口 $port 未被占用"
  fi
done
✅  UDP端口 5775 未被占用
✅  UDP端口 6831 未被占用
✅  UDP端口 6832 未被占用
root@uat:/data/projects/easewise/easewise-back# 

三、分布式追踪系统部署

1、部署Jaeger

Jaeger All-in-One 包含了 Collector、Query、Agent、UI 等所有组件,适合测试 / 中小规模生产环境快速部署:

bash 复制代码
docker run --rm -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 14250:14250 \
  -p 14268:14268 \
  -p 14269:14269 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

部署完成后,可通过docker ps | grep jaeger确认容器是否正常运行。

2、部署otel-collector:

bash 复制代码
docker run -d --name otel-collector \
  -p 4317:4317 \
  -p 4318:4318 \
  -v $(pwd)/coll-config.yaml:/etc/otelcol-contrib/config.yaml \
  otel/opentelemetry-collector-contrib:latest 

OTel Collector 负责统一接收各服务的追踪数据,处理后转发至 Jaeger,需先创建配置文件coll-config.yaml

bash 复制代码
# 完整的 coll-config.yaml(包含 traces + logs 处理)
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  otlp:
    endpoint: "172.17.0.4:4317"  # 替换为Jaeger容器内网IP
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]

注意:Jaeger 容器内网 IP 需通过docker inspect jaeger | grep IPAddress查询,替换上述配置中的172.17.0.4

服务启动后查看日志信息:

bash 复制代码
root@master:/data/otel# docker logs otel-collector 
2026-01-26T07:36:00.584Zinfootelcol@v0.120.0/collector.go:339Received signal from OS{"signal": "terminated"}
2026-01-26T07:36:00.584Zinfoservice@v0.120.0/service.go:323Starting shutdown...
2026-01-26T07:36:00.585Zinfoextensions/extensions.go:68Stopping extensions...
2026-01-26T07:36:00.585Zinfoservice@v0.120.0/service.go:337Shutdown complete.
2026-01-26T07:36:01.427Zinfoservice@v0.120.0/service.go:193Setting up own telemetry...
2026-01-26T07:36:01.435Zinfoservice@v0.120.0/service.go:258Starting otelcol-contrib...{"Version": "0.120.1", "NumCPU": 80}
2026-01-26T07:36:01.435Zinfoextensions/extensions.go:40Starting extensions...
2026-01-26T07:36:01.436Zinfootlpreceiver@v0.120.0/otlp.go:116Starting GRPC server{"otelcol.component.id": "otlp", "otelcol.component.kind": "Receiver", "endpoint": "0.0.0.0:4317"}
2026-01-26T07:36:01.436Zinfootlpreceiver@v0.120.0/otlp.go:173Starting HTTP server{"otelcol.component.id": "otlp", "otelcol.component.kind": "Receiver", "endpoint": "0.0.0.0:4318"}
2026-01-26T07:36:01.436Zinfoservice@v0.120.0/service.go:281Everything is ready. Begin running and processing data.

3、配置服务器启动

以 Java 服务为例,使用 OpenTelemetry Java Agent 实现无侵入自动埋点,无需修改业务代码。

下载javaagent:

bash 复制代码
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.24.0/opentelemetry-javaagent.jar

启动服务:

bash 复制代码
java -javaagent:/data/projects/opentelemetry-javaagent.jar -Dotel.service.name=gateway -Dotel.exporter.otlp.endpoint=http://192.168.119.7:4317 -Dfile.encoding=utf-8 -jar gateway.jar 

参数说明:

  • otel.service.name:服务标识,Jaeger UI 中会按此名称筛选链路;
  • otel.exporter.otlp.endpoint:OTel Collector 的地址(优先用 gRPC 端口 4317);
  • 若仅需追踪数据,可添加-Dotel.logs.exporter=none关闭日志导出,避免冲突。

若为supervisor,服务器启动配置文件:

bash 复制代码
root@uat:/data/projects# cat /etc/supervisor/conf.d/gateway.conf
[program:gateway]
directory=/data/projects/
command=/bin/bash -c "java -javaagent:/data/projects/opentelemetry-javaagent.jar -Dotel.service.name=gateway -Dotel.exporter.otlp.endpoint=http://192.168.119.7:4318 -Dotel.logs.exporter=none -Dfile.encoding=utf-8 -jar gateway.jar"
autostart=true
autostart=true
autorestart=true
startsecs=5
startretries=3
user=root
redirect_stderr=false
stdout_logfile=/data/logs/gateway.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=3
stderr_logfile=/data/logs/gateway.err
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=3

4、验证链路采集

访问 Jaeger UI(浏览器打开http://服务器IP:16686):

  1. 在 "Service" 下拉框中选择配置的服务名(如gateway);
  2. 点击 "Find Traces",若服务有请求量,即可看到对应的追踪链路;
  3. 点击某条链路,可查看请求的全链路 Span、各 Span 耗时、调用关系等信息。

具体链路请求信息:

相关推荐
池央7 分钟前
CANN 算子生态的深度演进:稀疏计算支持与 PyPTO 范式的抽象层级
运维·人工智能·信号处理
Maynor9968 分钟前
OpenClaw 玩家必备:用 AI 自动追踪社区最新动态
java·服务器·人工智能
堕27413 分钟前
java数据结构当中的《排序》(一 )
java·数据结构·排序算法
OJAC11118 分钟前
当所有人都在说“运维稳了”,近屿智能看到了另一种可能
运维
禁默22 分钟前
打破集群通信“内存墙”:手把手教你用 CANN SHMEM 重构 AIGC 分布式算子
分布式·重构·aigc
亓才孓27 分钟前
[Class的应用]获取类的信息
java·开发语言
哈__30 分钟前
CANN加速3D目标检测推理:点云处理与特征金字塔优化
目标检测·3d·目标跟踪
人鱼传说32 分钟前
docker desktop是一个好东西
运维·docker·容器
开开心心就好35 分钟前
AI人声伴奏分离工具,离线提取伴奏K歌用
java·linux·开发语言·网络·人工智能·电脑·blender
80530单词突击赢1 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端