3. Prometheus 指标类型:Counter、Gauge、Histogram、Summary 的区别与适用场景
在构建误差预算台账时,选择正确的指标类型是数据可靠性的基石。Prometheus 提供了四种核心指标类型,每种类型对应不同的数据特征与查询模式。理解它们的差异,能帮助你在 SLO 监控中避免“用错尺子量错数据”的陷阱。
3.1 四种指标类型核心对比
| 指标类型 | 数据特征 | 典型值 | 适用场景 | 误差预算关键用途 |
|---|---|---|---|---|
| Counter | 只增不减(重启归零) | 请求总数、错误总数 | 累计计数类事件 | 计算错误率、请求速率 |
| Gauge | 可增可减,反映当前状态 | CPU 使用率、队列深度 | 瞬时值快照 | 饱和度监控、容量预警 |
| Histogram | 分桶计数 + 总和 + 总数 | 请求延迟分布 | 百分位估算、分布分析 | 延迟 SLO 合规判定 |
| Summary | 客户端预计算分位数 | 请求延迟 p99 | 已知分位数需求、低资源场景 | 精确分位数监控 |
实践建议:在误差预算台账中,Counter 和 Histogram 是最常用的组合。Counter 提供事件总量,Histogram 提供延迟分布,两者结合可精确计算“好事件”与“坏事件”的比例。
3.2 指标类型详解与选择决策
3.2.1 Counter:累计事件的基石
Counter 只允许单调递增,适合记录请求数、错误数、任务完成数等累计量。在 PromQL 中通常配合 rate() 或 increase() 函数使用,计算每秒速率或一段时间内的增量。
# 定义请求总数 Counter
http_requests_total{method="GET", endpoint="/api/v1/users"} 1024
# 查询每秒请求速率(5分钟窗口)
rate(http_requests_total[5m])
# 查询过去1小时错误数增量
increase(http_errors_total[1h])
常见误区:不要用 Counter 存储瞬时值(如当前连接数),也不要直接对 Counter 做平均值计算。Counter 的原始值只有在计算速率或增量时才有意义。
3.2.2 Gauge:瞬时状态的快照
Gauge 可增可减,反映系统当前状态。适用于内存使用量、队列深度、并发连接数、温度等。Gauge 不需要 rate() 函数,直接使用 avg()、max()、min() 等聚合函数即可。
# 定义当前内存使用量 Gauge
node_memory_usage_bytes{instance="web-01"} 8589934592
# 查询所有实例的平均内存使用率
avg(node_memory_usage_bytes / node_memory_total_bytes) * 100
3.2.3 Histogram:延迟分布的黄金标准
Histogram 将观测值放入预定义的桶(bucket)中,同时记录总和与总数。通过 histogram_quantile() 函数可以估算任意百分位数,是延迟 SLO 合规判定的首选。
# 定义请求延迟 Histogram(桶边界:0.1, 0.3, 1.0, 3.0, 10.0 秒)
http_request_duration_seconds_bucket{le="0.1"} 240
http_request_duration_seconds_bucket{le="0.3"} 680
http_request_duration_seconds_bucket{le="1.0"} 920
http_request_duration_seconds_bucket{le="3.0"} 990
http_request_duration_seconds_bucket{le="10.0"} 1000
http_request_duration_seconds_bucket{le="+Inf"} 1000
http_request_duration_seconds_sum 450.2
http_request_duration_seconds_count 1000
# 查询 p99 延迟(5分钟窗口)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
误差预算关键点:Histogram 的桶边界设计直接影响 SLO 合规判定的精度。例如,若 SLO 要求 99% 的请求在 500ms 内完成,则必须在 500ms 附近设置桶边界(如 0.4、0.5、0.6),否则无法准确判断合规比例。
3.2.4 Summary:客户端预计算分位数
Summary 在客户端直接计算分位数并暴露结果,适合已知分位数需求且希望减少服务端计算开销的场景。但 Summary 的分位数是固定的,无法像 Histogram 那样灵活查询任意百分位。
# 定义请求延迟 Summary(预计算 p50、p90、p99)
http_request_duration_seconds{quantile="0.5"} 0.12
http_request_duration_seconds{quantile="0.9"} 0.45
http_request_duration_seconds{quantile="0.99"} 1.20
http_request_duration_seconds_sum 450.2
http_request_duration_seconds_count 1000
选择建议:在误差预算台账中,优先使用 Histogram 而非 Summary。Histogram 支持聚合多个实例的分位数,而 Summary 无法跨实例聚合,这在微服务架构中是一个致命限制。
3.3 指标命名最佳实践
良好的指标命名是台账可维护性的基础。Prometheus 社区推荐遵循以下命名规范:
- 基础格式:
<namespace>_<subsystem>_<unit>[_<suffix>] - 使用下划线分隔:全部小写,单词间用下划线连接
- 单位后缀:指标名末尾标注单位,如
_seconds、_bytes、_total - 类型后缀:Counter 以
_total结尾,Histogram 桶以_bucket结尾 - 避免冗余:不要重复 namespace 或 subsystem 中的信息
| ✅ 推荐命名 | ❌ 不推荐命名 | 说明 |
|---|---|---|
http_requests_total |
http_requests |
缺少 _total 后缀,无法区分类型 |
http_request_duration_seconds |
http_latency |
缺少单位,无法确定是毫秒还是秒 |
node_memory_usage_bytes |
memory_used |
缺少 namespace 和单位 |
api_errors_total |
api_error_count |
使用 _total 而非 _count |
3.4 指标类型选择决策流程
3.5 误差预算台账中的指标类型映射
在服务画像驱动的方法论中,每种误差预算指标都有对应的 Prometheus 类型:
| 台账指标 | Prometheus 类型 | 命名示例 | PromQL 计算方式 |
|---|---|---|---|
| 请求总数 | Counter | http_requests_total |
rate(http_requests_total[5m]) |
| 错误总数 | Counter | http_errors_total |
rate(http_errors_total[5m]) |
| 错误率 | Gauge(计算后) | error_ratio |
rate(http_errors_total[5m]) / rate(http_requests_total[5m]) |
| 延迟分布 | Histogram | http_request_duration_seconds |
histogram_quantile(0.99, rate(..._bucket[5m])) |
| 延迟 SLO 合规比例 | Gauge(计算后) | latency_slo_compliance_ratio |
sum(rate(..._bucket{le="0.5"}[5m])) / sum(rate(..._count[5m])) |
| 当前饱和度 | Gauge | service_saturation_ratio |
queue_depth / max_queue_depth |
核心原则:原始数据使用 Counter 和 Histogram 采集,误差预算合规比例和饱和度等衍生指标使用 Gauge 存储计算结果。这种分层设计既保留了原始数据的可追溯性,又提供了高效的查询性能。
3.6 常见错误与避坑指南
- 用 Gauge 记录累计值:Gauge 在进程重启后会丢失历史趋势,Counter 配合
rate()才能正确计算速率。 - Histogram 桶边界过少:少于 5 个桶会导致分位数估算误差过大,建议至少 7-10 个桶。
- Summary 用于跨服务聚合:Summary 的分位数无法在服务端聚合,多实例场景下必须使用 Histogram。
- 指标命名缺少单位:没有单位的指标名会导致后续维护者无法确定数据含义,必须强制添加单位后缀。
- 忽略
_total后缀:Prometheus 社区规范要求 Counter 必须以_total结尾,否则可能被工具链误判。
台账初始化检查清单:在创建误差预算台账前,逐一确认每个指标的类型选择是否正确、命名是否符合规范、桶边界是否覆盖 SLO 阈值。这个检查步骤能避免 80% 以上的数据质量问题。