服务器链路追踪配置:从零搭建到验证的完整流程
如果你正在排查跨服务调用延迟,却只看到某个接口整体变慢,链路追踪就是用来把一次请求经过的每个服务、每个数据库调用串成时间线的工具。
本文以 OpenTelemetry 为例,讲清楚在 Linux 服务器上从零配置链路追踪的完整步骤,包括准备条件、采集器部署、采样策略、数据验证和常见报错处理。
先确认环境与前提条件
链路追踪不是装一个软件就能自动生效,它需要应用侧和采集侧配合。
开始前请确认以下条件:
- 服务器能访问外网或内部可用的追踪后端,用于上报数据。
- 应用使用的语言有对应的 OpenTelemetry SDK,例如 Java、Go、Python、Node.js。
- 服务器时间已同步,否则跨服务的时间线会对不上。用
timedatectl status确认 NTP 同步状态。 - 如果应用在容器里运行,容器需要能访问采集器的监听端口。
本文以单台 Linux 服务器部署 OpenTelemetry Collector 为例,后端使用兼容 OTLP 协议的服务。
如果你用的是其他追踪系统,采集器配置的 exporter 部分需要相应调整。
部署 OpenTelemetry Collector
Collector 是接收应用上报数据、再转发到后端的中间层。
它的好处是应用只需要指向 Collector,后端更换时不用改应用配置。
下载并安装 Collector:
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/latest/download/otelcol_linux_amd64.tar.gz
tar -xzf otelcol_linux_amd64.tar.gz
sudo mv otelcol /usr/local/bin/
otelcol --version
创建配置文件 /etc/otelcol/config.yaml,最小可用配置如下:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
exporters:
otlp:
endpoint: your-backend:4317
tls:
insecure: false
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
把 your-backend:4317 替换成你实际的后端地址。
如果后端在内网且不启用 TLS,可以把 insecure 设为 true,但生产环境建议开启 TLS。
用 systemd 启动 Collector:
sudo otelcol --config /etc/otelcol/config.yaml
确认进程和端口正常:
ss -tlnp | grep -E '4317|4318'
能看到监听端口说明 Collector 已启动。
如果端口没出现,先看启动日志里的报错,常见原因是配置文件缩进错误或端口被占用。
配置应用侧上报
应用需要引入对应语言的 OpenTelemetry SDK,并把上报地址指向 Collector。
以 Java 应用为例,使用自动探针是最省事的方式:
java -javaagent:/opt/opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-Dotel.exporter.otlp.endpoint=http://127.0.0.1:4317 \
-jar app.jar
关键参数说明:
otel.service.name是服务名,后端会按这个名字聚合链路,命名要见名知义。otel.exporter.otlp.endpoint指向 Collector 的 gRPC 端口。- 如果应用和 Collector 不在同一台机器,把
127.0.0.1换成 Collector 的实际 IP。
Python 应用可以用 opentelemetry-instrument 启动:
opentelemetry-instrument \
--traces_exporter otlp \
--exporter_otlp_endpoint http://127.0.0.1:4317 \
python app.py
采样策略怎么设才不丢关键数据
全量采集在高流量下会产生大量数据,存储和网络成本都会上升。
采样是在“看得全”和“花得起”之间做平衡。
常见做法:
- 开发测试环境用
always_on,保证每条链路都能看到。 - 生产环境用
parentbased_traceidratio,按比例采样,例如 10% 或 20%。 - 对错误请求单独保留,可以在 Collector 里用
tail_sampling处理器,把status.code = ERROR的链路全部留下。
在应用侧设置采样率的示例:
-Dotel.traces.sampler=parentbased_traceidratio \
-Dotel.traces.sampler.arg=0.1
这表示采样 10% 的链路。
调整后要观察后端的链路数量和存储增长,再决定是否继续调整。
验证配置是否生效
配置完成后不要只看进程在不在,要实际验证数据能不能查到。
按顺序检查:
- 应用启动日志里是否有 OpenTelemetry 初始化成功的提示,没有报 exporter 连接失败。
- 访问一个会触发多个服务调用的接口,制造一条真实链路。
- 在追踪后端按服务名和最近时间范围查询,看是否出现新的 trace。
- 点开一条 trace,确认 span 数量和调用顺序符合预期。
如果后端查不到数据,先在 Collector 所在服务器抓包或用 curl 测试上报端口连通性:
curl -v http://127.0.0.1:4318/v1/traces
返回非连接拒绝的错误说明端口可达,问题更可能在 exporter 配置或后端认证上。
容易踩的坑
- 服务名重复:多个应用用了同一个
service.name,链路会混在一起,排查时无法区分。 - 时间不同步:服务器时间偏差超过几秒,跨服务时间线会出现负耗时,看起来像 bug。
- 只配了应用没配 Collector:应用一直重试上报,日志里会有大量连接错误,但追踪数据一条都没有。
- 采样率设成 0:等于关闭追踪,配置看起来正常但永远查不到数据。
- 防火墙拦了 4317/4318:应用和 Collector 不在同一台机器时,需要放行这两个端口。
常见疑问
链路追踪和日志、指标有什么区别?
日志记录单点事件,指标反映聚合趋势,链路追踪解决的是“一次请求在多个服务之间怎么走、慢在哪一段”。
三者互补,不能互相替代。
Collector 挂了会影响业务吗?
应用上报失败通常不会阻塞主流程,SDK 会缓存或丢弃数据。
但追踪数据会缺失,所以 Collector 建议配置进程守护和基本监控。
采样率调低后还能排查问题吗?
可以结合 tail sampling,把错误链路和慢链路单独保留。
如果业务对可观测性要求高,优先保证错误和长尾请求的完整采集。
配置完成后,建议先在小流量服务上验证一周,确认数据完整性和存储成本都在可接受范围,再逐步推广到核心服务。
遇到查不到数据的情况,按“应用上报配置 → Collector 接收 → exporter 转发 → 后端存储”的顺序逐段排查,比反复改采样率更有效。