3. 可观测性三大支柱:日志、指标、追踪的概念与关系

在微服务架构中,系统被拆分为多个独立部署的服务实例,传统的“登录服务器查看日志”方式已无法应对分布式环境的复杂性。可观测性(Observability) 成为运维和诊断的核心能力,其技术基础由三大支柱构成:日志(Logging)、指标(Metrics) 和 追踪(Tracing)。理解三者的定义、差异与协作关系,是构建支付订单系统监控体系的第一步。

3.1 三大支柱的定义与核心特征

支柱 定义 数据形态 典型用途 存储与查询
日志(Logging) 记录离散事件的结构化或非结构化文本 单条记录,带时间戳、级别、消息体 错误排查、审计、详细调试 ELK / Loki / 文件
指标(Metrics) 可聚合的数值型时间序列数据 计数器、直方图、仪表盘 告警、容量规划、趋势分析 Prometheus / InfluxDB
追踪(Tracing) 记录请求在分布式系统中的完整调用链路 Span 树,包含 Trace ID、Span ID、耗时 性能瓶颈定位、依赖关系分析 Jaeger / Zipkin / Tempo
关键区别:日志回答“发生了什么”,指标回答“系统状态如何”,追踪回答“请求去了哪里、花了多久”。三者互补,缺一不可。

3.2 三大支柱在微服务中的协作关系

在支付订单系统中,一个典型的用户下单请求会跨越多个微服务:API Gateway → 订单服务 → 支付服务 → 库存服务 → 通知服务。仅靠单一数据源无法完整还原问题全貌。下图展示了三大支柱如何协同工作:

可观测性三大支柱协作关系图 可观测性三大支柱协作关系 微服务调用链:API Gateway → 订单服务 → 支付服务 → 库存服务 → 通知服务 日志(Logging) 记录每个服务的请求/响应 错误堆栈、业务异常 审计日志、慢查询日志 存储:ELK / Loki 指标(Metrics) QPS、延迟 P99、错误率 CPU/内存/连接数 队列深度、DB 连接池 存储:Prometheus 追踪(Tracing) Trace ID 串联全链路 Span 耗时、服务依赖图 跨服务调用拓扑 存储:Jaeger 三者通过 Trace ID 关联:日志中嵌入 Trace ID,指标聚合时按 Trace ID 分组

3.3 为什么在微服务中三者缺一不可?

支付订单系统对可靠性要求极高,任何一笔交易失败都需要快速定位根因。以下场景说明三大支柱如何互补:

  • 场景一:订单支付超时
    • 指标:支付服务 P99 延迟从 200ms 飙升到 5s,触发告警。
    • 追踪:查看 Trace,发现支付服务调用第三方网关耗时 4.8s。
    • 日志:搜索对应 Trace ID 的日志,看到“第三方网关返回 503”错误详情。
  • 场景二:库存扣减失败导致订单取消
    • 指标:库存服务错误率从 0.1% 上升到 15%。
    • 追踪:发现所有失败请求都经过同一个 Redis 缓存节点。
    • 日志:该节点日志显示“连接池耗尽,获取连接超时”。
  • 场景三:新版本上线后性能退化
    • 指标:订单服务 CPU 使用率翻倍,但 QPS 未变。
    • 追踪:对比新旧版本的 Span 耗时,发现新增的“用户积分计算”Span 耗时 800ms。
    • 日志:该 Span 对应的日志显示 SQL 查询未命中索引,全表扫描。
常见误区:不要认为“有了链路追踪就不需要日志”或“指标可以替代追踪”。三大支柱的数据粒度不同:指标是聚合的、日志是离散的、追踪是请求维度的。缺少任何一个,都会在特定场景下产生“盲区”。

3.4 三大支柱在 NestJS 微服务中的落地路径

在后续章节中,我们将基于 NestJS 生态逐步集成三大支柱。下表给出了每个支柱在 NestJS 中的典型技术选型与集成方式:

支柱 NestJS 集成方案 关键库/工具 数据流向
日志 自定义 Logger 实现,注入 Trace ID Pino / Winston + nestjs-pino 应用 → 控制台 → 日志收集器 → 存储
指标 Interceptor 采集请求指标,暴露 /metrics 端点 prom-client + @willsoto/nestjs-prometheus 应用 → Prometheus → Grafana 告警/展示
追踪 全局 Interceptor 创建/传播 Trace ID,自动上报 Span @opentelemetry/instrumentation-http + @opentelemetry/exporter-jaeger 应用 → OpenTelemetry SDK → Jaeger Collector → 存储

3.5 核心概念关系总结

下图以支付订单系统为例,展示一个完整请求在三大支柱视角下的数据关联:

支付请求的三大支柱数据关联示例 支付请求在三大支柱中的数据关联示例 请求:用户下单支付 ¥99.9 → Trace ID: abc-123-def 日志 [abc-123-def] 订单创建成功 [abc-123-def] 支付请求发送 [abc-123-def] 支付回调:成功 [abc-123-def] 库存扣减完成 每条日志携带 Trace ID 指标 支付请求总数 +1 支付成功数 +1 支付延迟:320ms 订单金额累计 +99.9 聚合后按标签分组 追踪 Span: 订单服务 (120ms) Span: 支付服务 (200ms) Span: 库存服务 (50ms) Span: 通知服务 (30ms) Span 树展示调用拓扑
核心结论:日志提供细节,指标提供趋势,追踪提供结构。三者通过 Trace ID 和 标签(Labels) 关联,形成完整的可观测性数据平面。在支付订单系统中,任何一笔交易的失败都应该能够通过“指标告警 → 追踪定位 → 日志取证”的闭环快速解决。