今天分享下如何使用 opentelementry 和 jaeger 采集服务的 trace。
一. 简介
1.1 opentelementry

OpenTelemetry(简称 OTel)是一个开源的分布式链路追踪(Distributed Tracing)、指标(Metrics)和日志(Logs)的标准化框架,旨在提供一套统一的工具、API 和 SDK,帮助开发者在复杂的分布式系统中实现可观测性(Observability)。
核心目标
解决分布式系统中可观测性工具碎片化的问题:传统上,不同厂商(如 Jaeger、Zipkin、Prometheus 等)有各自的追踪 / 监控方案,导致开发者需要适配多种接口。OpenTelemetry 提供了 ** vendor-agnostic(与厂商无关)** 的标准,让数据可以无缝对接不同的后端(如存储、分析平台),避免绑定特定工具。
核心功能
1.分布式链路追踪(Tracing)
o追踪请求在分布式系统中的流转路径(如从用户请求到 API 网关、微服务、数据库等)。
o通过跨度(Span) 记录每个服务的处理过程(耗时、状态、元数据等),多个相关 Span 组成一条追踪链路(Trace)。
o基于 W3C Trace Context 规范(包含 traceparent、tracestate 等 HTTP 头),实现跨服务、跨平台的追踪上下文传递。
2.指标(Metrics)
o收集系统或应用的数值型数据(如 QPS、延迟、错误率、内存使用率等),用于监控和告警。
o支持多种指标类型(计数器、 gauge、直方图等),并可与追踪数据关联分析。
3.日志(Logs)
o收集系统运行过程中的日志信息,支持结构化日志,并能与追踪、指标数据关联(如通过 Trace ID 将日志绑定到具体链路)。
核心组件
·API:定义了跨语言的接口(如创建 Span、记录指标的方法),开发者无需关心底层实现。
·SDK:各语言的具体实现(如 Java、Python、Go 等),提供自动 instrumentation(自动埋点,如对 HTTP 框架、数据库驱动的追踪)和手动埋点能力。
·Collector:一个可配置的代理服务,负责接收、处理(过滤、转换、聚合)和导出追踪 / 指标 / 日志数据到后端(如 Jaeger、Zipkin、Prometheus、Elasticsearch 等)。
·Instrumentation Libraries:针对常见框架 / 库的预定义埋点(如 Spring Boot、Django、MySQL 驱动等),开发者无需手动修改代码即可启用追踪。
工作流程
1.埋点:通过 SDK 或自动埋点工具,在应用中生成追踪、指标或日志数据。
2.上下文传递:在服务调用时(如 HTTP、RPC),通过 Trace Context 传递追踪上下文(确保跨服务链路的连贯性)。
3.数据收集:数据被发送到 OpenTelemetry Collector 或直接导出到后端。
4.存储与分析:后端工具(如 Jaeger)存储并可视化追踪链路,帮助定位性能瓶颈或错误。
优势
·标准化:遵循开放标准(如 W3C Trace Context),避免厂商锁定。
·多语言支持:覆盖主流编程语言(Java、Python、Go、C++ 等)。
·灵活性:可对接多种后端工具(追踪、监控、日志系统)。
·自动化:大量预定义的 instrumentation 库减少手动埋点成本。
OpenTelemetry 已成为云原生领域可观测性的事实标准,被 CNCF(云原生计算基金会)托管,与 Kubernetes、Prometheus 等生态工具紧密集成。
github 地址:https://github.com/open-telemetry 里面有多个仓库,比如 collecktor、SDK 等。
官方文档: https://opentelemetry.io/docs
1.2 jaeger
Jaeger 是Uber公司研发,后来贡献给CNCF的一个分布式链路追踪软件,这里我只用 jager 的 UI,用来查看 opentelementry 中的 trace。
jaeger官网:https://www.jaegertracing.io/
github地址: https://github.com/jaegertracing/jaeger

二. 部署
数据流:HotROD(nginx)-->otel-collector reveiver --> otel-collector export-->jaeger receiver <--jaeger UI
2.1 部署collector和jaeger
1.拉取镜像
# dockerhub
docker pull otel/opentelemetry-collector-contrib:0.136.0
# ghr.io
docker pull ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.136.0\
# dockerhub
docker pull jaegertracing/all-in-one:1.72.0
2.编写 docker-compose.yaml
services:
# 1. OTLP Collector:统一接收各端OTLP数据
otel-collector:
image:otel/opentelemetry-collector-contrib:0.136.0
container_name: otel-collector
hostname: otel-collector
restart: always
ports:
- "4317:4317"# gRPC端口(各端OTLP数据默认发送端口)
- "4318:4318"# HTTP端口
volumes:
- $PWD/otel/otel-collector-config.yml:/etc/otelcol-contrib/config.yaml# 挂载配置文件
networks:
- otlp-network # 所有服务加入同一网络,确保互通
# 2. Jaeger:可视化Trace链路(开箱即用,无需额外配置)
jaeger:
image: jaegertracing/all-in-one:1.72.0
container_name: jaeger
hostname: jaeger
restart: always
ports:
- "16686:16686"# Web界面端口
networks:
- otlp-network
networks:
otlp-network:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
3.编辑配置文件
receivers:
# 接收各端的OTLP gRPC/HTTP数据(核心)
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
# 简单处理:添加服务环境标签(可选,便于筛选)
resource:
attributes:
- key: env
value: "dev"
action: insert
exporters:
# 转发数据到Jaeger(地址为Jaeger容器名:端口,同一网络可直接用容器名)
otlp/jaeger:
endpoint: "jaeger:4317"
tls:
insecure: true
service:
pipelines:
# Trace数据流水线:接收→处理→转发
traces:
receivers: [otlp]
processors: [resource]
exporters: [otlp/jaeger]
4.启动
docker compose up -d
5.浏览器访问测试
http://<server IP>

2.2 部署HotROD示例应用
HotROD(按需出行)是一个演示应用程序,由多个微服务组成,展示了 OpenTelemetry 和分布式追踪的使用。
1.添加HostROD服务
# 3. jaeger应用示例jaeger-example-hotrod:image: jaegertracing/example-hotrod:1.72.0container_name: jaeger-example-hotrodhostname: jaeger-example-hotrodrestart: alwayscommand: ["all", "--otel-exporter=otlp"] # 原命令的参数,启动所有子服务ports:- "7070-7073:8080-8083"# 映射 HotROD 服务端口(8080 为入口,8081-8083 为子服务)environment:# 对接otel-collector的 HTTP- OTEL_EXPORTER_OTLP_ENDPOINT=http://192.168.31.103:4318depends_on:- jaeger- otel-collectornetworks:- otlp-network
2. 验证
1)访问 HotROD 前端:打开 http://<server IP>

2)在 Jaeger UI 查看追踪:回到 http://



这些参数是 Jaeger 中一条分布式追踪(Trace)的关键汇总信息,各参数含义如下:
·Trace Start
表示这条追踪的开始时间,即整个请求链路中第一个操作(Span)开始的时间点,这里是 October 18 2025, 23:04:17.479。
·Duration
代表这条追踪的总持续时间,也就是从追踪开始到所有相关操作(Span)都完成所花费的时间,此处为 692.42ms,反映了整个请求处理的耗时情况。
·Services
指这条追踪涉及的服务数量,这里是 6,说明整个请求链路涉及了 6 个不同的服务参与处理。
·Depth
表示追踪的深度,即调用链的层级深度,这里是 4,意味着在整个调用过程中,操作的嵌套层级最多有 4 层。
·Total Spans
代表这条追踪中Span 的总数量,Span 是分布式追踪中的基本单元,每个 Span 对应一个操作(如一次 RPC 调用、一次数据库查询等),这里有 39 个 Span,说明整个请求链路包含了 39 个这样的操作。
2.3 追踪nginx示例
注意使用限制:
·Nginx OTel 模块目前仅支持 gRPC 方式上报,不支持 HTTP 方式上报。
·Nginx OTel 模块版本说明:
o≥ 0.1.2:支持将 Nginx OTel 采集到的 Nginx 调用链直接转发上报至可观测链路 OpenTelemetry 版。
o≤ 0.1.1:Nginx OTel 模块不支持设置 gRPC 鉴权 Token,因此您需要部署 OpenTelemetry Collector。
前往Docker官网,搜索并拉取带有-otel后缀的Nginx镜像(如nginx:1.26.0-otel),通过标准容器启动流程部署服务。Nginx 1.27.5 版本及以上默认采用的是 0.1.2 版本的Nginx OTel 模块。
若要为 Nginx 启用链路追踪,还需要在 Nginx 主配置文件/etc/nginx/nginx.conf中加载 OTel 模块并添加配置项。关于 OTel 模块的更多参数配置信息,请参见ngx_otel_module 模块文档。
·全局配置:为所有 HTTP 请求开启链路追踪。
load_module modules/ngx_otel_module.so; # 加载 ngx_otel_module
...
http {
...
otel_exporter {
endpoint "${GRPC_ENDPOINT}"; # 前提条件中获取的 gRPC 接入点
header Authentication "${GRPC_TOKEN}"; # 前提条件中获取的鉴权 Token
}
otel_trace on; # 开启链路追踪
otel_service_name ${SERVICE_NAME};# 应用名
otel_trace_context propagate; # 向下游服务注入Trace上下文
...
}
·为单个 Location 开启链路追踪
load_module modules/ngx_otel_module.so; # 加载 ngx_otel_module
...
http {
otel_exporter {
endpoint "${GRPC_ENDPOINT}"; # 前提条件中获取的 gRPC 接入点
header Authentication "${GRPC_TOKEN}"; # 前提条件中获取的鉴权 Token
}
server {
listen 127.0.0.1:80;
location /hello {
otel_trace on; # 只为 127.0.0.1:80/hello 开启链路追踪
otel_service_name ${SERVICE_NAME}# 应用名
otel_trace_context propagate; # 向下游服务注入Trace上下文
...
}
}
}
追踪示例:
1.docker-compose 中添加 nginx 服务
# 采集 nginx 应用
nginx-otel-test-docker:
image: nginx:1.28.0-alpine3.21-otel # 默认包含 0.1.2 版本 nginx-moduel-otel 模块的 nginx 镜像
container_name: nginx-otel-test-docker
hostname: nginx-otel-test-docker
restart: always
volumes:
- ./nginx_conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx_conf/default.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "1666:80"
depends_on:
- jaeger
- otel-collector
networks:
- otlp-network
nginx.conf 关键配置:
# 加载 ngx_otel_module
load_module modules/ngx_otel_module.so;
...
http {
...
# OTEL配置
otel_exporter {
endpoint otel-collector:4317;
}
otel_trace on;# 开启链路追踪
otel_service_name nginx-otel-test-docker; # 应用名,自己自定义
otel_trace_context propagate;# 向下游服务注入Trace上下文
include /etc/nginx/conf.d/*.conf; # 包含conf.d目录下的所有配置文件
}
default.conf 配置:
server {
listen 80;
server_namelocalhost;
location / {
root /usr/share/nginx/html;
indexindex.html index.htm;
}
error_page 500 502 503 504/50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
2.访问 nginx

3.到 jaeger中查看会看到多一个 nginx-otel-test-docker 的服务

点击 Find Traces:

可以看到刚刚访问的/,点击可查看详情:
2.4 对接 openobserve
上篇文章有说到 openobserve 也可以解决 trace,这里演示下
1.到数据源查看对接参数

2.修改otel-collector-config.yml
exporters:
# 转发数据到Jaeger(地址为Jaeger容器名:端口,同一网络可直接用容器名,可以用 grpc 也可以用 http)
otlp/jaeger:
endpoint: "jaeger:4317"
tls:
insecure: true
# 对接 openobserve
# http方式
otlphttp/openobserve:
endpoint: http://192.168.31.103:5080/api/default
headers:
Authorization: Basic YWRtaW5AZWFzeW9wcy5vbmxpbmU6R0pvbXRrUmV6SzFtM1FjWQ==
stream-name: default
service:
pipelines:
# Trace数据流水线:接收→处理→转发
traces:
receivers: [otlp]
processors: [resource]
exporters: [otlp/jaeger,otlphttp/openobserve]
3.重启otel-collector
docker restart otel-collector
4.到 openobserve 中查看


可以发现和 jaeger 中看到的是一致的。下期再介绍下如何在 k8s 中无侵入采集服务的 trace。

