三套系统各看各的
故障复盘最头疼的是:告警在 Prometheus 里,调用链在 SkyWalking,日志在 ELK,三套 ID 对不上,定位一个问题要在三个系统间反复横跳。有次一个下单超时,我在 SkyWalking 看到 span 慢,却没法直接拿到那次请求的日志,只能靠时间戳去 ELK 捞,捞出来还不一定对得上,最后花了 25 分钟才定位到是一条慢 SQL。今年我们把可观测性统一到 OpenTelemetry,用一套 API 和协议把 Trace、Metric、Log 串起来,复盘效率明显提升,平均定位时间降到 5 分钟以内。
三件套怎么统一
OpenTelemetry 的核心思路是:用同一个 TraceId 贯穿三者。它不是某个具体的存储或界面,而是一套标准和一组 SDK,后端可以接 Prometheus、Jaeger、OTLP Collector 等。
- Trace:一次请求跨服务串联,每个跨度带 spanId 和 traceId;
- Metric:用同一套语义约定(如 http.server.request.duration)打点,避免各团队命名打架;
- Log:日志里注入 traceId,ELK 里直接按 traceId 把一条请求的所有日志捞出来。
关键在于日志侧。我们在 Logback 的 MDC 里塞 traceId,这样每条日志都带上,ELK 里一个查询就能拉全:
<appender>
<encoder>
<pattern>%d %X{trace_id} %X{span_id} %msg%n</pattern>
</encoder>
</appender>
接入 Otel 的日志桥接后,MDC 自动被填充,业务代码完全无感,不用在每行日志里手动传 traceId。这一步是统一可观测性的地基。
Java Agent 无侵入接入
最省事的是用 javaagent,不用改业务代码,对存量服务尤其友好:
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
-jar order-service.jar
agent 自动埋点 Spring、JDBC、Kafka、Redis 等常见框架。我们 18 个微服务接入只花了半天,因为都不用改代码。但要小心:agent 默认全量埋点,QPS 高的服务导出量很大,得配合采样,否则 OTLP 出口把网络打满。我们一开始没配采样,Collector 的入口带宽直接到 90%,加了采样才下来。另外 agent 版本要和 Collector 的 OTLP 协议版本对齐,否则字段解析会丢。
采样策略是门权衡
我们用了尾部采样(Tail Sampling),在 Collector 侧判断:错误请求和慢请求 100% 留,正常请求按 10% 抽:
processors:
tail_sampling:
policies:
- name: errors
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow
type: latency
latency: { threshold_ms: 500 }
- name: probabilistic
type: probabilistic
probabilistic: { sampling_percentage: 10 }
实测采样后 trace 存储从每天 1.2TB 降到 140GB,成本降 88%,而故障相关的 trace 一个没丢。尾部采样比头部采样的优势是能基于"结果"决定留不留,错误和慢请求不会因概率被丢。我们为此还加了一条"新版本路由"策略,灰度版本的流量 100% 采样,方便对比新旧版差异。
接入后的真实收益
上周一次超时,我直接在 Grafana 点开一条慢 trace,顺着 span 看到是某个 Redis 调用 P99 1.8 秒,再用 traceId 去日志系统秒级捞出对应日志,定位到一条没加索引的查询。过去这套动作要 20 分钟,现在 3 分钟。统一可观测性省下的不只是存储,更是值班同学半夜的心力。还有一个附带好处:新来的同学不用再学三套系统的查询语法,一套 Grafana 看板全搞定。
踩过的几个坑
- Collector 单点:一开始只部署一个 Collector 实例,它挂了全公司 trace 断流,后来改成两实例加负载均衡;
- context 传播丢失:某个老服务用自研线程池,没把 Otel Context 传进去,跨线程后 trace 断了,得用 Context.taskWrapping 包一层;
- 日志量暴涨:traceId 进日志后,ELK ingestion 涨了 15%,靠采样和索引裁剪压住。
小结
OpenTelemetry 的价值不在某个单点功能,而在于"一套标准"。Trace、Metric、Log 共享语义和 ID,agent 降低接入成本,采样控制开销。落地时先把 ID 打通,再逐步把三方系统迁到 OTLP 协议,别一上来就想替换全部。我们目前是 SkyWalking 和 OTel 并存过渡,新服务全走 OTel,老的慢慢迁。如果你也在被三套系统割裂折磨,强烈建议从统一 traceId 这一步开始。