Prometheus监控原理#
一句话答案#
Prometheus 基于 Pull 模式抓取 metrics 端点,多维标签查询(PromQL),配合 Grafana 可视化和 AlertManager 告警。
核心要点
架构: Target(/metrics) ← Prometheus(pull+存储+查询) → Grafana(展示) / AlertManager(告警)
Metric 类型: Counter(累计)/ Gauge(瞬时值)/ Histogram(分布)/ Summary
PromQL 查询: rate(http_requests_total[5m]) 过去5分钟请求速率
Java 接入: micrometer-registry-prometheus + Spring Boot Actuator 自动暴露 /actuator/prometheus
TSDB 存储引擎(数据怎么落盘)#
一条样本 = (metric{labels}, timestamp, value);同一组 labels 的样本序列叫一个 series。
- head block(内存)+ WAL: 最近约 2 小时的样本先写内存中的 head block,同时顺序追加到 WAL(预写日志)。WAL 保证进程崩溃后能回放恢复内存数据,防丢点。
- 2h block 落盘: 每约 2 小时把 head block 切出,压成一个不可变的磁盘 block(按时间分块,目录含 chunks + index + meta)。
- compaction(压缩合并): 后台周期把多个小 block 合并成更大的 block,删除过期数据、降低索引与文件数,提升查询效率。
- 倒排索引检索 series: block 内为每个 label 键值对(如
job="api")建倒排索引,指向包含该 label 的 series 列表。PromQL 按 label 过滤时(如http_requests_total{job="api",code="500"}),对各 label 的 posting list 求交集快速定位目标 series,再读对应时间范围的样本,避免全扫。
Pull 抓取 + 服务发现#
Prometheus 按 scrape_interval 定时 HTTP GET 各 target 的 /metrics,解析文本格式样本入库。target 列表不写死——靠 service discovery(K8s SD / Consul / file_sd 等)动态生成:例如 K8s SD 监听 API Server,Pod 增删自动更新抓取目标,再经 relabel_configs 过滤、改写标签。Target 不可达时记 up=0,所以”被监控对象挂了”本身就是一个可告警的指标。
Histogram 分位数怎么算#
Histogram 在客户端预设若干 bucket(桶,按 le 上界划分),每来一个观测值,所有 le ≥ 该值 的桶计数 +1 —— 是累积计数(le=+Inf 桶即总数)。查询时 histogram_quantile(0.99, rate(http_duration_bucket[5m])):先找 P99 落在哪个桶区间,再在该桶内线性插值估算分位值。
- 优点: 计算在服务端做,多实例的 bucket 可直接相加后再算分位(可聚合)。
- 代价: 精度取决于桶的划分,桶太粗则插值误差大;Summary 在客户端直接算好分位但不可跨实例聚合,按需取舍。
面试回答(2分钟版)
Prometheus是云原生监控的事实标准,核心特点是Pull模式——Prometheus服务端定时去各个Target的/metrics端点主动拉取指标数据,而不是让应用推送。这种设计的好处是监控系统和被监控服务解耦,Target挂了Prometheus也能感知到。采集到的数据存在本地时序数据库中,通过PromQL查询,比如rate(http_requests_total[5m])可以算出过去5分钟的请求速率。指标有四种类型:Counter只增不减适合总请求数、总错误数,Gauge可增可减适合当前连接数、队列长度,Histogram按桶统计分布适合延迟百分位,Summary类似但在客户端计算。在Java项目中接入很简单,引入micrometer-registry-prometheus加上Spring Boot Actuator就会自动暴露/actuator/prometheus端点。配合Grafana做可视化看板,AlertManager做告警通知,形成完整的监控体系。
追问与易错
追问方向:
- “Pull 模式和 Push 模式有什么区别?”→ Pull 模式由 Prometheus 主动拉取,Target 挂了能立即感知,且不会因 Target 过多把监控服务打爆;Push 模式(如 Graphite)由应用推送,适合短生命周期 Job,Prometheus 用 Pushgateway 兼容
- “Prometheus 数据量大了怎么扩展?”→ 单机 Prometheus 有存储上限,可用 Thanos 或 VictoriaMetrics 做长期存储和跨集群聚合查询;也可按业务分片部署多个 Prometheus 实例
- “Counter 和 Gauge 怎么选?”→ 只增不减的指标用 Counter(如请求总数、错误总数),配合 rate() 算速率;可增可减的瞬时值用 Gauge(如当前连接数、CPU 使用率、队列长度)
易错点:
- ❌ 说不清数据怎么存——head block 内存 + WAL 防丢,每 2h 落盘成不可变 block,compaction 合并,靠 label 倒排索引检索 series
- ❌ 以为 Histogram 桶是独立计数——是累积计数(
le上界,le ≥ 值的桶都 +1),分位靠 histogram_quantile 在桶内线性插值 - ❌ 分不清 Histogram 和 Summary——Histogram 服务端算分位、可跨实例聚合但有插值误差;Summary 客户端算精确分位但不可聚合
- ❌ 以为 target 要手动配——生产靠 service discovery(K8s SD 等)动态发现,relabel 改写标签