3. Prometheus 指标基础:Counter、Gauge、Histogram、Summary 的定义与适用场景

在构建证书轮换调度器的性能基准测试时,选择正确的指标类型是数据可靠性的基石。Prometheus 提供了四种核心指标类型:Counter、Gauge、Histogram 和 Summary。每种类型都有其独特的语义、数学特性和适用场景。误用指标类型会导致监控数据失真,甚至引发错误的告警与扩缩容决策。

3.1 指标类型总览

下表从核心特性、数据行为与典型用途三个维度,对四种指标类型进行横向对比:

指标类型 核心特性 数据行为 典型用途
Counter 只增不减(除重启外) 单调递增的累计值 请求总数、错误次数、任务完成数
Gauge 可增可减,反映当前快照 任意上下波动 CPU 使用率、内存占用量、队列深度
Histogram 分桶计数 + 总和 + 总次数 观测值落入预定义桶的累计计数 请求延迟分布、响应大小分布
Summary 流式分位数 + 总和 + 总次数 在客户端计算分位数并暴露 SLI 延迟分位数(p50/p90/p99)
关键认知:Counter 和 Gauge 是“原始值”指标,适合直接告警与趋势观察;Histogram 和 Summary 是“分布型”指标,用于计算分位数和服务等级目标(SLO)合规性。

3.2 Counter:单调递增的累计器

Counter 是最简单的指标类型,其值在进程生命周期内只增不减。即使系统重启,Counter 也会从 0 重新开始累计。在 PromQL 中,通常使用 rate() 或 increase() 函数将 Counter 转换为每秒速率或增量,从而获得有意义的业务视图。

  • 适用场景:证书轮换总次数、轮换失败次数、已处理证书数、API 调用总量。
  • 不适用场景:温度、水位、当前连接数等需要反映瞬时状态的值。
  • 命名惯例:通常以 _total 结尾,例如 cert_rotation_total。
# 证书轮换调度器中的 Counter 示例
# HELP cert_rotation_total 证书轮换操作的总次数
# TYPE cert_rotation_total counter
cert_rotation_total{status="success"} 1024
cert_rotation_total{status="failure"} 13

# PromQL 查询:过去 5 分钟的轮换速率
rate(cert_rotation_total[5m])

3.3 Gauge:瞬时快照的测量仪

Gauge 用于记录可上下波动的瞬时值。它不关心历史累计,只反映“此时此刻”的状态。Gauge 可以直接用于告警,无需经过 rate() 转换。

  • 适用场景:当前待轮换证书队列长度、证书剩余有效期(秒)、调度器工作线程数、内存使用量。
  • 不适用场景:累计计数、速率计算。
  • 典型 PromQL:avg_over_time(cert_queue_depth[5m]) 或直接 cert_queue_depth > 100 触发告警。
# 证书轮换调度器中的 Gauge 示例
# HELP cert_remaining_seconds 证书距离过期剩余的秒数
# TYPE cert_remaining_seconds gauge
cert_remaining_seconds{cn="api.example.com"} 2592000
cert_remaining_seconds{cn="web.example.com"} 86400

# PromQL 查询:剩余有效期不足 7 天的证书数量
count(cert_remaining_seconds < 604800)

3.4 Histogram:可聚合的分布统计

Histogram 将观测值(如请求延迟)分配到预定义的桶(bucket)中,同时记录所有观测值的总和(_sum)和总次数(_count)。Histogram 的优势在于可聚合性:多个实例的 Histogram 数据可以合并计算全局分位数。

  • 适用场景:证书轮换延迟分布、API 响应时间、证书签名耗时。
  • 桶设计原则:桶的边界应覆盖目标分布的 95%~99% 范围,且在关键阈值附近(如 SLO 边界)加密桶。
  • PromQL 分位数计算:使用 histogram_quantile() 函数。
# 证书轮换延迟的 Histogram 示例
# HELP cert_rotation_duration_seconds 证书轮换操作的耗时分布
# TYPE cert_rotation_duration_seconds histogram
cert_rotation_duration_seconds_bucket{le="0.1"} 240
cert_rotation_duration_seconds_bucket{le="0.5"} 890
cert_rotation_duration_seconds_bucket{le="1.0"} 1020
cert_rotation_duration_seconds_bucket{le="5.0"} 1024
cert_rotation_duration_seconds_bucket{le="+Inf"} 1024
cert_rotation_duration_seconds_sum 312.5
cert_rotation_duration_seconds_count 1024

# PromQL 查询:p99 延迟
histogram_quantile(0.99, rate(cert_rotation_duration_seconds_bucket[5m]))
注意:Histogram 的桶数量直接影响内存开销和查询性能。对于证书轮换这类低频操作,建议使用 5~8 个桶;对于高频 API,桶数可控制在 10~15 个。过多的桶会导致指标基数爆炸。

3.5 Summary:客户端预计算的分位数

Summary 直接在客户端计算分位数(如 p50、p90、p99),并将结果暴露为独立的时序。Summary 不依赖桶,因此无法在服务端进行跨实例聚合。它适用于已知分位数需求且不需要全局聚合的场景。

  • 适用场景:单实例的延迟分位数监控、不需要跨实例合并的 SLI 报告。
  • 与 Histogram 的核心区别:Summary 的分位数在客户端计算,无法聚合;Histogram 的分位数在服务端计算,可以聚合。
  • 典型 PromQL:直接引用分位数指标,如 cert_rotation_duration_seconds{quantile="0.99"}。
# 证书轮换延迟的 Summary 示例
# HELP cert_rotation_duration_seconds 证书轮换操作的耗时(Summary)
# TYPE cert_rotation_duration_seconds summary
cert_rotation_duration_seconds{quantile="0.5"} 0.23
cert_rotation_duration_seconds{quantile="0.9"} 0.87
cert_rotation_duration_seconds{quantile="0.99"} 2.45
cert_rotation_duration_seconds_sum 312.5
cert_rotation_duration_seconds_count 1024

3.6 指标类型选择决策流程

下面的 SVG 流程图展示了在证书轮换调度器场景中,如何根据数据特性选择正确的指标类型:

证书轮换调度器指标类型选择决策流程 观测数据点 是否只增不减? (重启除外) 是 Counter 否 是否反映当前 瞬时状态? 是 Gauge 否 是否需要跨实例 聚合分位数? 是 Histogram 否 Summary 说明: • 证书轮换总次数、失败次数 → Counter • 当前队列深度、剩余有效期 → Gauge • 轮换延迟分布(需聚合)→ Histogram | 单实例分位数 → Summary

3.7 证书轮换场景的指标映射

将上述理论映射到证书轮换调度器的性能基准测试中,我们为每个关键观测点分配了具体的指标类型:

观测维度 指标名称 指标类型 选择理由
轮换操作总量 cert_rotation_total Counter 累计计数,用于计算吞吐量(ops/s)
轮换失败次数 cert_rotation_failures_total Counter 单调递增,用于计算错误率
待轮换队列深度 cert_rotation_queue_depth Gauge 瞬时值,反映调度器积压压力
证书剩余有效期 cert_remaining_seconds Gauge 瞬时值,用于告警阈值判断
轮换操作延迟 cert_rotation_duration_seconds Histogram 需要跨实例聚合 p99 延迟,评估 SLO
证书签名耗时 cert_signing_duration_seconds Summary 单实例内部性能分析,无需全局聚合
基准测试实践:在证书轮换调度器的性能基准测试中,Histogram 是核心指标类型。通过合理设置桶边界(如 0.1s、0.5s、1s、2s、5s),可以精确测量不同负载下的延迟分布,并计算 p50/p90/p99 延迟。结合 Counter 的速率数据,即可绘制出完整的吞吐量-延迟曲线。

3.8 常见误区与避坑指南

  • 误区一:用 Gauge 记录累计值。Gauge 在重启或采集间隔内可能丢失增量信息,应使用 Counter + rate()。
  • 误区二:对 Counter 直接求平均值。Counter 是累计值,直接平均无意义,必须先用 rate() 转换为每秒速率。
  • 误区三:在 Summary 上使用 histogram_quantile()。Summary 的分位数已在客户端计算,无法在服务端重新聚合。
  • 误区四:Histogram 桶边界设置过密。过多的桶会导致每个序列产生大量时间序列,增加 Prometheus 内存压力。
  • 误区五:忽略 _sum 和 _count 的用途。这两个辅助指标可用于计算平均值(_sum / _count),是 Histogram 和 Summary 的通用能力。