Prometheus 监控系统搭建:从指标采集到告警通知
Prometheus 是云原生计算基金会(CNCF)的毕业项目,已经成为监控领域的标准工具。它采用“拉取”模式:监控目标暴露 /metrics 端口,Prometheus 定期去抓取。这种设计让监控系统不依赖目标端主动上报,天然适合动态扩容的环境。
一、架构概览
Exporter → Prometheus Server → AlertManager → 通知渠道
↓
Grafana (可视化)
Exporter 负责把系统或应用的指标翻译成 Prometheus 格式,AlertManager 负责把告警去重、分组后发到邮件/IM,Grafana 负责可视化。这四层分工清晰,也方便各管一段:数据采集和存储归 Prometheus,告警归 AlertManager,展示归 Grafana,任何一层都可以独立升级或替换,不需要推倒重来。
二、指标类型:先搞懂四种基础类型
| 类型 | 说明 | 典型例子 |
|---|---|---|
| Counter | 只增不减的计数器 | 请求总数、CPU 时间 |
| Gauge | 可增可减的当前值 | 内存使用量、在线连接数 |
| Histogram | 观测值分布(分位数) | 请求延迟 P50/P95/P99 |
| Summary | 客户端计算的摘要 | 同 Histogram,客户端算好分位 |
绝大多数系统监控只需要 Counter 和 Gauge,理解这两类就够搭起一套能用的监控。另外建议了解一下命名约定:Prometheus 约定 Counter 以 _total 结尾(如 node_cpu_seconds_total),单位信息放进指标名(如 _bytes、_seconds),这样查询和团队协作时不会产生歧义。
三、安装配置
# docker-compose.yml
version: '3'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
scrape_interval 的默认值是 15s,抓取频率越高,指标越平滑,但存储和开销也越大;对主机监控 15s 或 30s 通常足够,没必要一味追求高频。规则评估间隔(evaluation_interval)建议与抓取间隔一致,避免告警计算基于过期数据。
Prometheus 的抓取目标、告警规则文件都写在 prometheus.yml 里:
global:
scrape_interval: 15s
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: node
static_configs:
- targets: ["node-exporter:9100"]
四、PromQL 常用查询
# CPU 使用率
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 内存使用率
100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)
# 磁盘使用率
100 * (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})
这三条分别对应服务器最核心的三项:CPU、内存、磁盘,加进 Grafana 就能组成一个基础主机看板。
五、告警规则
groups:
- name: server
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU usage above 80%"
for: 5m 表示条件持续 5 分钟才触发,避免瞬时抖动引发误报。告警规则建议按 severity 分级:warning(可观察)、critical(需要立刻处理),并接上 AlertManager 通知:
route:
receiver: "webhook"
routes:
- match:
severity: critical
receiver: "pager"
receivers:
- name: "webhook"
webhook_configs:
- url: "https://hooks.slack.com/services/xxx"
六、Grafana 可视化
Grafana 首次登录默认账号 admin/admin。推荐两步:先导入官方的 Node Exporter Full 看板(ID 1860),再用上面的 PromQL 加一个自定义看板,把首页 PV、接口延迟、错误率这类业务指标也接进来。看板数量不在多,能让人 30 秒内判断“系统现在健不健康”就够了。
一个真实场景
某站点在促销前一天接入了这套监控。促销当天凌晨,CPU 告警(持续 5 分钟超过 80%)被触发,值班同学顺着 Grafana 看到商品页接口的延迟指标飙高,定位到是数据库慢查询,赶在流量上来之前完成了索引优化。整场促销零事故。如果当时没有监控,大概率是用户先发现页面打不开,再层层排查。
监控上线检查清单
- 每个服务器都部署了 node-exporter
- 关键应用暴露了自定义指标
- 告警至少接了一个通知渠道,且有人真的能看到
- 告警阈值避免误报(加
for持续时长) - Grafana 看板能让新人 30 秒看懂
常见问题
指标数据越来越大,磁盘不够怎么办? Prometheus 是时序数据库,数据会持续增长。常规做法:一是调整保留周期 --storage.tsdb.retention.time(比如保留 15 天,历史数据交给对象存储归档);二是用 --storage.tsdb.retention.size 限制存储上限;三是给业务类指标单独一个实例,避免和主机指标混在一起。
告警一晚上响个不停,怎么治理? 这是“告警风暴”。常见原因:阈值设得太敏感、没有加 for 持续时长、告警没有去重分组。建议按下面顺序治理:先给每条告警加 for(至少 1-5 分钟),再用 AlertManager 的 group_by 把同类告警合并成一条,最后对已知的维护窗口做静默(silence),并定期清理没人处理的告警规则。
只监控 CPU 内存够吗? 不够,那只覆盖了“服务器层面”。业务层面同样重要:接口延迟、错误率、队列积压、数据库慢查询,这些才是用户能感知的。node-exporter 只是第一步,下一步让应用通过 Prometheus 客户端库暴露自定义指标,或使用现成的集成(如 nginx exporter、mysql exporter),形成“主机 + 中间件 + 业务”三层覆盖。
Grafana 打开很慢怎么办? 先检查看板是不是一次加载了太多查询和大时间范围,其次确认 Grafana 与 Prometheus 之间的网络延迟,必要时开启 Grafana 的缓存。看板数量建议控制在 10 个以内,把常用的钉在侧边栏,减少每次加载的计算量。
参考:Prometheus 官方文档 https://prometheus.io/docs/introduction/overview/
参考:Grafana 官方文档 https://grafana.com/docs/
参考:AlertManager 配置 https://prometheus.io/docs/alerting/latest/alertmanager/