Week 4 · Chapter 2 · 可观测性实践

复习难度:⭐⭐⭐ | 预计时长:2-3小时 | 重点程度:中


监控三支柱

Metrics(指标):量化数据(QPS、延迟、错误率)
Logs(日志):事件记录(某时刻发生了什么)
Traces(链路追踪):请求路径(从哪里来,到哪里去)

Prometheus

核心概念

Pull 模式:Prometheus 定期从应用拉取指标
Exporter:应用暴露 /metrics 端点,Prometheus 拉取

数据类型:
  Counter:只增不减(请求次数、错误次数)
  Gauge:可增可减(当前在线人数、CPU使用率)
  Histogram:分布统计(延迟分布)
  Summary:分位点(TP99/TP999)

你审批平台里的用法

import "github.com/prometheus/client_golang/prometheus"

var (
    approvalDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "approval_duration_seconds",
            Buckets: []float64{0.01, 0.05, 0.1, 0.5, 1, 5},
        },
        []string{"workflow_id", "node_type"},
    )

    approvalTotal = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "approval_total",
            Help: "Total approval count",
        },
        []string{"status"}, // approved/rejected/cancelled
    )
)

链路追踪(OpenTelemetry)

原理:每次请求生成一个 TraceID,沿途透传
Span:每个服务的处理单元,嵌套父子关系

关键字段:
  TraceID:整个请求链路的唯一ID
  SpanID:当前服务的唯一ID
  ParentSpanID:父服务的SpanID
// 在 Go 中使用 OpenTelemetry
span := tracer.StartSpan(ctx, "ApproveOrder")
defer span.End()

span.SetAttributes(
    attribute.String("order.id", orderID),
    attribute.String("user.id", userID),
)

日志规范

结构化日志 > 文本日志

好的日志格式:
{
  "time": "2026-04-12T21:00:00Z",
  "level": "INFO",
  "trace_id": "abc123",
  "msg": "审批单创建成功",
  "order_id": "xxx",
  "user_id": "xxx",
  "duration_ms": 23
}

禁止:
  - 日志中包含密码、Token、身份证号
  - 用日志打印敏感数据
  - 日志级别混乱(INFO打DEBUG量级)

你简历里的 Prometheus 用法

// IAM 慢查询监控
# 慢查询次数
iam_slow_query_total{query_type="list_users"} 15

// 接口延迟
iam_query_duration_seconds{quantile="0.99"} 0.085

// 告警规则示例
- alert: HighErrorRate
  expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
  for: 2m
  labels:
    severity: critical

面试重点

Q:如何排查一个接口慢的问题?

① 看 APM 链路追踪,找到耗时最长的 Span ② 看该服务的 Prometheus 指标(CPU/内存/GC) ③ 看日志,是否有慢查询或锁等待 ④ 逐层往下追(网关→服务→DB/缓存/MQ)

Q:Prometheus 如何保证高可用?

① Prometheus 是无状态的,多实例独立拉取 ② Thanos / Cortex 实现指标长期存储和全局聚合 ③ Alertmanager 做告警聚合和去重