微服务架构下,一个用户请求可能经过 API 网关、多个微服务、数据库和缓存,一旦出现延迟或错误,很难定位是哪个环节出了问题。这正是全链路追踪(Distributed Tracing)与性能监控要解决的核心问题。本文从实际排查场景出发,介绍如何利用 OpenTelemetry 和 Prometheus 这些开源工具,逐步构建起可观测性体系。
排查问题的第一步:确认数据从哪来
当线上出现“请求变慢”或“偶发超时”时,我们往往先看日志,但微服务日志分散在各节点,难以串起完整调用链。全链路追踪的核心是给每个请求分配一个全局唯一的 Trace ID,并在跨服务调用时传递上下文,从而把散落的日志、指标串成一条完整的链路。
OpenTelemetry(简称 OTel)是目前业界标准的可观测性框架,它提供统一的 API、SDK 和协议,用于生成、采集和导出追踪(traces)、指标(metrics)和日志(logs)。根据官方文档,OpenTelemetry 是厂商中立的开源框架,已获得超过 90 家可观测性厂商的支持,并被众多库、服务和应用集成。这意味着你无需绑定特定厂商,即可实现埋点数据的标准化采集。
设计链路追踪:从 Trace 到 Span
在实施全链路追踪前,需要理解几个核心概念:
- Trace:一次完整请求的端到端视图,由多个 Span 组成。
- Span:Trace 中的单个工作单元,代表一次操作,如 HTTP 调用、数据库查询等。每个 Span 包含名称、开始/结束时间、属性(如 HTTP 状态码)和父子关系。
- Context 传播:通过 HTTP 头(如 W3C Trace-Context)在服务间传递 Trace ID 和 Span ID,确保链路完整。
设计时,你需要确定哪些服务需要埋点,以及如何传递上下文。例如,在 Java 中可使用 OpenTelemetry Java Agent 实现无侵入式埋点,在 Python 中可使用 opentelemetry-python 库手动或自动埋点。官方文档提供了多种语言的接入指南,可参考相应文档。
埋点实施:自动与手动结合
埋点是链路追踪的关键步骤,常见方式有两种:
- 自动埋点:通过 Agent 或库自动拦截常见框架(如 Spring Boot、Flask)的请求,自动生成 Span。优点是接入快,缺点是可能无法覆盖业务自定义逻辑。
- 手动埋点:在业务代码中显式创建 Span,可记录更细粒度的信息,如缓存命中、消息队列发送等。适合需要深度定制的场景。
建议先使用自动埋点快速搭建基础链路,再针对关键业务路径补充手动埋点。例如,在创建订单时,可手动添加一个“处理订单”Span,并设置属性如订单 ID、用户 ID,方便后续检索。
性能监控:用 Prometheus 采集指标
全链路追踪解决“请求如何流动”的问题,而性能监控解决“系统负载如何”的问题。Prometheus 是一个开源系统监控和告警工具,它采集并存储指标数据(如请求数、错误率、延迟),并以时间序列形式保存,支持通过 PromQL 进行查询和告警。
Prometheus 的核心是拉取模型:被监控服务暴露 /metrics 端点,Prometheus 定期抓取。OpenTelemetry 可以作为 Prometheus 的指标采集器,通过 OTLP 协议将指标发送到 Prometheus 或兼容后端。官方文档指出,OpenTelemetry 提供供应商无关的方式接收、处理和导出遥测数据,因此你可以将 OTel 采集到的指标同时导出到 Prometheus 和追踪后端。
数据关联:将 Trace 与 Metrics 结合
单独看 Trace 或 Metrics 都有局限:Trace 能展示单个请求的细节,但难以聚合;Metrics 能反映整体趋势,但无法定位到具体请求。因此,需要将二者关联。
常见做法是在指标中携带 Trace ID 或 Service 名称等标签,这样当指标异常时,可以快速跳转到对应的 Trace 详情。例如,在 Prometheus 中记录请求延迟时,可以添加标签 trace_id,但注意高基数问题(每个请求唯一值会导致指标爆炸),通常只保留 service、route 等低基数标签,而将 Trace ID 放在日志或追踪系统中,通过时间窗口和维度关联。
落地步骤:从零到一搭建全链路追踪
以下是一个典型实施步骤,适用于小型团队快速启动:
- 选择后端:先确定 Trace 和 Metrics 的存储后端。可选用 Jaeger、Zipkin 等开源追踪系统,或云厂商托管服务;Metrics 可选 Prometheus + Grafana。
- 接入 OpenTelemetry:在服务中引入 OpenTelemetry SDK,配置导出器(Exporter)指向后端。
- 配置上下文传播:确保所有服务使用相同的传播格式(如 W3C Trace-Context),否则链路会断裂。
- 部署 Agent/库:根据语言选择自动埋点方式,并验证 Span 是否生成。
- 导出指标:配置 OpenTelemetry Metrics SDK 或使用 Prometheus 客户端库暴露指标。
- 创建仪表盘:在 Grafana 中配置 Prometheus 数据源,创建请求延迟、错误率、饱和度等 RED/USE 指标仪表盘。
- 设置告警:基于 Prometheus 告警规则,对高延迟、高错误率设置告警。
常见误区与失败条件
实施过程中,以下误区常导致效果不佳:
- 忽略上下文传播:如果服务间调用时未传递 Trace ID,链路会断裂,无法串联。务必检查 HTTP 客户端是否自动注入 header。
- 采样策略不当:全量采集会带来性能开销和存储压力,建议按需采样(如头部采样、尾部采样)。但采样率过低会丢失关键请求,需要权衡。
- 指标高基数:在指标中加入高基数标签(如用户 ID)会导致存储爆炸,应避免。
- 只追踪不监控:只有 Trace 没有 Metrics,无法从全局发现趋势;反之亦然。两者需结合。
总结与进一步排查
全链路追踪与性能监控是微服务可观测性的两大支柱。通过 OpenTelemetry 统一埋点,将 Trace 和 Metrics 导出到 Prometheus 等后端,你可以快速定位性能瓶颈和错误源头。但记住,工具只是辅助,关键在于理解业务链路和监控指标。
如果遇到链路不完整或指标缺失,首先检查上下文传播和导出配置;如果性能开销过大,调整采样策略;如果告警频繁,优化阈值和维度。持续迭代,才能建立有效的监控体系。
参考资料
延伸阅读
