2、监控指标设计:Counter、Gauge、Histogram、Summary 四种核心指标类型详解与选型
监控指标选型这事儿,我见过太多团队踩坑了。有人把所有数据都塞进 Counter,结果算平均值算到怀疑人生。也有人非要用 Histogram 统计个在线人数,白白浪费存储空间。说白了,选错指标类型,就像拿菜刀拧螺丝——不是不能用,但你会很痛苦。
今天咱们就把 Prometheus 这四种核心指标类型掰开揉碎讲清楚。我会结合自己踩过的坑,告诉你什么场景该用谁。
2.1 Counter:只增不减的计数器
Counter 是最直观的指标类型。它只支持两种操作:初始化、加一。嗯,你没看错,不能减。
典型场景:
- HTTP 请求总数
- 错误发生次数
- 任务执行次数
- CPU 时间片累计
代码示例:
// 记录 API 调用次数
api_requests_total{method="GET", endpoint="/users"} 1024
// 记录错误次数
errors_total{service="auth", type="timeout"} 57
核心要点:Counter 只能算速率,不能算均值。比如「每秒请求数」用 rate() 函数算,「累计请求数」直接查值就行。
我的经验:我习惯把 Counter 的指标名以 _total 结尾。这是 Prometheus 的命名规范,但更重要的是——看到这个名字我就知道它是累加的,不会傻乎乎去求平均值。
2.2 Gauge:可增可减的仪表盘
Gauge 就像汽车仪表盘上的速度表。它能上能下,反映的是某个时刻的瞬时值。
典型场景:
- 当前内存使用量
- 在线用户数
- 队列长度
- CPU 温度
代码示例:
// 当前内存使用量(字节)
memory_usage_bytes{host="web-01"} 8589934592
// 当前在线用户数
active_users{service="chat"} 1423
注意:Gauge 的值会随时间波动。如果你用 Gauge 记录「累计请求数」,那每次重启服务都会归零。我曾经见过有人用 Gauge 记录请求总数,结果每次部署后数据都断崖式下跌——排查了半天才发现是类型选错了。
什么时候用 Gauge?
- 数据可以上升也可以下降
- 你关心的是当前值,不是变化速率
- 数据会随着系统状态自然波动
2.3 Histogram:分布统计的利器
Histogram 是我个人最喜欢的指标类型。它不仅能记录数值,还能告诉你这些数值是怎么分布的。
举个例子:你记录了 1000 次 API 请求的延迟。平均值是 200ms,但这里面可能有 900 次是 10ms,100 次是 2s。平均值完全掩盖了真相。Histogram 就能告诉你:90% 的请求在 50ms 以内,99% 在 500ms 以内。
核心概念:
- Bucket(桶):预先定义好的数值区间,比如 ≤10ms、≤50ms、≤100ms、≤500ms
- Count:落在每个桶里的样本数量
- Sum:所有样本值的总和
代码示例:
// 定义 Histogram 指标
http_request_duration_seconds_bucket{le="0.1"} 240
http_request_duration_seconds_bucket{le="0.5"} 890
http_request_duration_seconds_bucket{le="1.0"} 950
http_request_duration_seconds_bucket{le="+Inf"} 1000
http_request_duration_seconds_count 1000
http_request_duration_seconds_sum 157.3
选桶技巧:桶的分布要符合你的业务特征。我一般会先跑一周数据,看看 P50、P90、P99 大概在什么范围,然后围绕这些值设置桶。桶太少会丢失精度,桶太多会浪费存储。
典型场景:
- 请求延迟分布
- 响应体大小分布
- 数据库查询耗时分布
2.4 Summary:预计算的分位数
Summary 和 Histogram 很像,都能算分位数。但区别在于:Summary 在客户端就完成了分位数计算,Histogram 是在服务端算的。
代码示例:
// Summary 指标
rpc_duration_seconds{quantile="0.5"} 0.052
rpc_duration_seconds{quantile="0.9"} 0.210
rpc_duration_seconds{quantile="0.99"} 0.850
rpc_duration_seconds_count 1000
rpc_duration_seconds_sum 157.3
重要提醒:Summary 的分位数是预定义的,你不能在查询时动态调整。比如你只定义了 P50、P90、P99,那就没法算 P95。而 Histogram 可以在查询时用 histogram_quantile() 函数算任意分位数。
什么时候用 Summary?
- 你明确知道需要哪些分位数
- 客户端计算能减轻服务端压力
- 指标数量少,且分位数固定不变
2.5 选型决策指南
说了这么多,到底该怎么选?我整理了一个简单的决策流程:
| 你的需求 | 推荐类型 | 原因 |
|---|---|---|
| 只关心总量或速率 | Counter | 简单高效,存储成本低 |
| 关心当前瞬时值 | Gauge | 可增可减,反映实时状态 |
| 需要分析数据分布 | Histogram | 灵活查询任意分位数 |
| 分位数固定且客户端计算 | Summary | 减少服务端计算压力 |
避坑指南:我曾经在一个高并发系统里用 Summary 记录请求延迟,结果发现客户端计算分位数时内存暴涨。后来换成 Histogram,把计算压力转移到服务端,问题就解决了。所以——如果你的客户端资源紧张,优先考虑 Histogram。
2.6 实战中的组合使用
实际项目中,很少只用一种指标类型。我通常的做法是:
- 基础监控用 Counter:请求数、错误数、任务执行次数
- 资源监控用 Gauge:CPU、内存、磁盘、连接数
- 性能监控用 Histogram:延迟、响应大小、查询耗时
- 特定场景用 Summary:比如 SLA 报告中只需要 P99 和 P999
举个例子,一个完整的 HTTP 服务监控指标集可能是这样的:
# Counter:请求总量和错误量
http_requests_total{method="GET", status="200"}
http_errors_total{method="GET", status="500"}
# Gauge:当前连接数和队列长度
http_active_connections
http_queue_length
# Histogram:请求延迟分布
http_request_duration_seconds_bucket{le="0.05"}
http_request_duration_seconds_bucket{le="0.1"}
http_request_duration_seconds_bucket{le="0.5"}
http_request_duration_seconds_bucket{le="1.0"}
你看,每种指标各司其职。Counter 告诉你「发生了多少」,Gauge 告诉你「现在怎么样」,Histogram 告诉你「到底有多慢」。三者配合,才能看清系统的全貌。
最后说一句:指标类型选型没有绝对的对错,但有明显的优劣。我的建议是——先搞清楚你要回答什么问题,再选合适的指标类型。别为了用 Histogram 而用 Histogram,也别因为偷懒把所有数据都塞进 Gauge。
下一章我们会聊「标签设计:如何避免高基数陷阱」。嗯,这个话题我也有不少血泪史,到时候慢慢讲。