大数跨境
0
0

opentelemetry+jaeger采集服务 trace(docker)

opentelemetry+jaeger采集服务 trace(docker) 运维小白成长之路
2025-10-26
1

今天分享下如何使用 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 规范(包含 traceparenttracestate 等 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> :16686

2.2 部署HotROD示例应用

HotROD(按需出行)是一个演示应用程序,由多个微服务组成,展示了 OpenTelemetry 和分布式追踪的使用。

1.添加HostROD服务

# 3. jaeger应用示例 jaeger-example-hotrod:  image: jaegertracing/example-hotrod:1.72.0  container_name: jaeger-example-hotrod  hostname: jaeger-example-hotrod  restart: always  command: ["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:4318  depends_on:     - jaeger     - otel-collector  networks:     - otlp-network

 2. 验证

1)访问 HotROD 前端:打开 http://<server IP> :8080,点击「Call a Ride」发起测试请求。

2)在 Jaeger UI 查看追踪:回到 http:// :16686,在「Service」下拉框选择「frontend」,点击「Find Traces」,可查看请求的完整链路追踪数据(包含各微服务调用耗时、依赖关系等)。

这些参数是 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。


好了,今天的分享就到这里了,希望对大家有所帮助。如果觉得还不错的话,各位看官动动小手点赞加关注,点击下面的链接可以直接进入本公众号,查看历史文章,谢谢大家^_^
                 





【声明】内容源于网络
0
0
运维小白成长之路
1234
内容 119
粉丝 0
运维小白成长之路 1234
总阅读144
粉丝0
内容119