4. 指标基础:Counter / Gauge / Histogram / Summary 与 Prometheus 数据模型

在可观测性三信号中,指标(Metrics)是量化系统状态与行为最直接的手段。Prometheus 作为云原生生态的事实标准,定义了四种核心指标类型与一套严格的数据模型。理解这些基础是构建联动修复策略的前提。

4.1 四种核心指标类型

Prometheus 客户端库提供四种指标类型,分别适用于不同的监控场景。下表从语义、典型用途与数学特性三个维度进行对比:

类型 语义 典型用途 数学运算 重置行为
Counter 只增不减的累计值 请求总数、错误计数、CPU 时间 差值、速率(rate/irate) 进程重启时归零
Gauge 可增可减的瞬时值 内存使用量、连接数、温度 平均值、最大值、分位数 随采样实时变化
Histogram 分桶统计 + 总和 + 计数 请求延迟分布、响应大小分布 分位数(histogram_quantile) 桶与总和一起重置
Summary 客户端预计算分位数 SLI 延迟分位数(p50/p99) 直接读取分位数标签 滑动窗口内计算
选型建议:需要计算速率或累计趋势时用 Counter;需要观察瞬时水位时用 Gauge;需要从服务端计算任意分位数时用 Histogram;需要精确预计算分位数且接受客户端开销时用 Summary。

4.2 Prometheus 数据模型

Prometheus 将所有指标存储为带时间戳的时间序列,每个序列由 Metric Name 和一组 Labels 唯一标识。数据模型的核心结构如下:

<metric_name>{<label_name>="<label_value>", ...}  <value>  <timestamp>

# 示例
http_requests_total{method="GET", endpoint="/api/v1/users", status="200"}  1024  1700000000

关键设计原则:

  • Metric Name:必须符合正则 [a-zA-Z_:][a-zA-Z0-9_:]*,通常包含单位与语义(如 http_request_duration_seconds)。
  • Labels:维度标签,用于多维度聚合。每个时间序列由 labels 组合唯一确定。
  • Sample:一个时间点上的数值,由 float64 值 + 毫秒精度时间戳组成。
  • Timestamp:由 Prometheus Server 在采集时追加,客户端上报时通常省略。
Prometheus 数据模型结构 Prometheus 数据模型结构 时间序列 (Time Series) Metric Name http_requests_total Labels (维度) {method="GET", status="200"} Sample (样本) 1024 @ 1700000000 说明: 每个唯一的 Metric Name + Labels 组合构成一个独立的时间序列。 PromQL 通过标签选择器(如 {method="GET"})实现多维聚合查询。

4.3 指标采集方式

Prometheus 采用 Pull 模型主动从目标端点抓取指标,同时也支持 Pushgateway 用于短期任务。采集流程分为三个阶段:

  1. 暴露端点:应用集成 Prometheus 客户端库,在 HTTP 路径 /metrics 上暴露指标。
  2. 服务发现与目标管理:Prometheus Server 通过静态配置或服务发现(Kubernetes、Consul 等)获取目标列表。
  3. 抓取与存储:按 scrape_interval(默认 15s)拉取数据,解析后存入本地 TSDB。
采集配置示例(prometheus.yml):
scrape_configs:
  - job_name: 'my-app'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: '/metrics'
    scheme: 'http'

4.4 四种指标类型在 PromQL 中的典型用法

指标类型 常用 PromQL 函数 查询示例 说明
Counter rate(), irate(), increase() rate(http_requests_total[5m]) 计算每秒请求速率,适合告警与趋势分析
Gauge avg(), max(), min() avg(memory_usage_bytes{app="web"}) 直接聚合瞬时值,适合资源水位监控
Histogram histogram_quantile() histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) 服务端计算 p99 延迟,需配合 _bucket 指标
Summary 直接读取 _p50, _p99 标签 http_request_duration_seconds_summary{p99="0.5"} 客户端已算好分位数,查询简单但无法跨维度聚合
Prometheus Pull 模型采集流程 Prometheus Pull 模型采集流程 应用实例 /metrics 端点暴露 服务发现 K8s / Consul / 静态配置 Prometheus Server 抓取 → 解析 → 存储 采集流程说明: 1. 应用通过客户端库在 /metrics 暴露指标数据。 2. Prometheus 通过服务发现获取目标列表,按 scrape_interval 发起 HTTP GET 请求。 3. 解析响应中的文本格式指标,以时间序列形式存入本地 TSDB。
避坑提示:Counter 类型指标在进程重启后会归零,使用 rate() 函数时需注意重置检测;Histogram 的 bucket 配置必须覆盖预期的延迟范围,否则 histogram_quantile 会返回不准确的结果。

4.5 指标类型选择决策树

在实际工程中,快速选择正确的指标类型可以遵循以下决策逻辑:

  • 是否只增不减? → 是 → Counter(如请求总数、错误计数)
  • 是否可增可减? → 是 → Gauge(如内存使用量、当前连接数)
  • 是否需要分析分布? → 是 → 进入分位数决策:
    • 需要服务端灵活计算任意分位数? → Histogram
    • 需要客户端预计算固定分位数且查询简单? → Summary