基于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 存储 / 可视化" 的经典架构,整体流程如下:
- 业务 Java 服务通过 OpenTelemetry Java Agent 实现无侵入自动埋点,生成追踪数据;
- 追踪数据通过 OTLP(OpenTelemetry Protocol)协议发送到 OTel Collector;
- OTel Collector 对数据进行批处理优化后,转发至 Jaeger 后端;
- 运维 / 开发人员通过 Jaeger UI 查看全链路追踪信息,定位问题。
- 仅仅作为在测试环境内使用,若上线生产则需增加认证以及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):
- 在 "Service" 下拉框中选择配置的服务名(如
gateway); - 点击 "Find Traces",若服务有请求量,即可看到对应的追踪链路;
- 点击某条链路,可查看请求的全链路 Span、各 Span 耗时、调用关系等信息。

具体链路请求信息:
