【前情提要】 Postfix 配好了,Alertmanager 能发邮件了。小林第一次收到告警邮件,兴奋得不行。但老周说:“光收邮件不够,你得知道告警来了之后该干什么。”当天凌晨,小林的手机响了——磁盘告警。
一、凌晨两点的邮件
小林是被手机震动吵醒的。
他迷迷糊糊地摸过手机,屏幕亮得刺眼:
发件人:xiaolin@qq.com
主题:[FIRING:1] HighDiskUsage (warning)
时间:2026-09-14 02:13:47
内容:
根分区使用率超过 85%
根分区使用率已持续 5 分钟超过 85%,当前值 87.3%
小林盯着屏幕看了五秒,脑子才转过来。
“磁盘满了?”
他翻了个身,想继续睡:“明天再说吧……”
然后他想起老周上周说的话:
“告警响了,你不处理,它就会一直响。而且明天可能就不是 87% 了,是 97%。到时候你连 SSH 都连不上,因为系统写不了日志、建不了临时文件。”
小林一个激灵坐起来,打开电脑,连上 SSH。
二、先看磁盘:df -h
“第一件事,看哪个分区满了。”小林自言自语,回忆老周教的命令。
│ │ │ │ (可视化) │ │ (告警路由) │ │ │ └──────────────┘ └────────┬─────────┘ │ │ │ │ └──────────────────────────────────────────┼───────────────────┘ │ │ 发送邮件 ▼ ┌──────────────┐ │ QQ 邮箱 │ │ (收件箱) │ └──────────────┘
“这个图你存好。”老周说,“以后忘了,看一眼就想起来了。”
“我有个问题。”小林说,“exporter 把指标暴露在哪?Prometheus 怎么拿到?”
“exporter 是一个 HTTP 服务,把指标暴露在一个端口上。比如 node_exporter 默认监听 9100 端口,你访问 http://localhost:9100/metrics,就能看到一堆指标。Prometheus 定期去这个 URL 拉数据,这叫‘拉取模式(pull)’。”
“那 Prometheus 多久拉一次?”
“默认 15 秒。”老周说,“你可以配。拉取频率太高,数据量大;太低,告警不及时。15 秒是常用值。”
“那 Alertmanager 怎么知道要告警?”
“Prometheus 里配告警规则。比如‘CPU 超过 80% 持续 2 分钟’,规则匹配了,Prometheus 就把告警推给 Alertmanager。Alertmanager 再根据路由规则,发给对应的人。”
小林在笔记本上画了一遍图,虽然画得歪歪扭扭,但结构记住了。
四、指标是什么?
“你刚才说‘指标’。”小林问,“指标到底长啥样?”
“指标就是一个名字,加一堆标签,加一个数值,加一个时间戳。”老周说,“比如:”
node_cpu_seconds_total{cpu="0", mode="idle"} 12345.67 1694592000
“拆开看:”
node_cpu_seconds_total:指标名。表示 CPU 累计使用时间,单位秒。{cpu="0", mode="idle"}:标签。cpu="0"表示第 0 个核心,mode="idle"表示空闲模式。12345.67:数值。累计空闲了 12345.67 秒。1694592000:时间戳。Unix 时间戳,表示采集时间。
“所以一条指标,就是‘某个时间点,某个东西的某个值’。”老周说,“你以后分析监控数据,就是在分析这些数值的变化。”
“那指标有几种类型?”
“四种。”老周说,“但你入门阶段,记住两种就够。”
Counter(计数器)
“只增不减。比如 CPU 累计时间、请求总数、错误总数。你关心的是‘增长速度’,不是‘当前值’。比如‘每秒请求数’,就是 Counter 的增长率。”
Gauge(仪表盘)
“可增可减。比如当前内存使用量、当前磁盘使用率、当前在线用户数。你关心的是‘当前值’。”
“另外两种是 Histogram 和 Summary,用于统计分布,你以后用到再说。”老周说,“你现在记住 Counter 和 Gauge 就够了。”
小林记下:
- Counter:只增不减,关心增长率(如请求总数)
- Gauge:可增可减,关心当前值(如内存使用量)
- Histogram/Summary:统计分布,入门暂不涉及
五、拉取模式 vs 推送模式
“我再问你一个问题。”老周说,“Prometheus 去 exporter 拉数据,这叫‘拉取模式’。那有没有‘推送模式’?”
“有吧?”
“有。”老周说,“有些监控系统是推送模式,exporter 主动把数据推给监控服务器。但 Prometheus 用的是拉取模式。为什么?”
小林摇头。
“三个原因。”老周竖起三根手指。
第一,Prometheus 知道谁是谁。
“拉取模式下,Prometheus 配置里明确写了要拉哪些目标。如果某个目标挂了,Prometheus 拉不到数据,up 指标变成 0,你就知道它挂了。推送模式下,目标挂了就不推了,你反而不知道它是挂了还是没数据。”
第二,配置集中。
“拉取模式下,要监控哪些目标,都在 Prometheus 配置里。你改配置、重启,就生效。推送模式下,每个目标都要配推送到哪,分散。”
第三,调试方便。
“你 curl http://localhost:9100/metrics 就能看到指标,不用等推送。出问题也好排查。”
“所以,Prometheus 选择拉取模式,是为了‘知道目标在不在’。 你以后面试被问到,就这么说。”
小林记下:
- Prometheus 用拉取模式
- 目标挂了,
up指标变 0,能发现 - 配置集中,调试方便
六、告警:什么时候该喊人?
“监控装好了,数据也有了。”小林问,“那什么时候该告警?”
“好问题。”老周说,“告警不是越多越好。告警太多,你会麻木;告警太少,你会漏掉。”
“那怎么定?”
“三个原则。”老周竖起三根手指。
第一,告警要可行动。
“收到告警,你得知道该干什么。比如‘磁盘使用率 90%’,你知道要清理磁盘。但‘CPU 使用率 60%’,你收到也不知道该干啥,那就别告。”
第二,告警要有阈值和持续时间。
“不是一超过就告。比如 CPU 超过 80%,持续 2 分钟才告。避免‘瞬间抖动’触发告警。”
第三,告警要分级。
“严重告警,比如服务挂了,发邮件、发短信。警告告警,比如磁盘快满了,发邮件就行。别所有告警都‘夺命连环 call’。”
“你以后配告警,先问自己:这个告警,我半夜收到会起来处理吗? 如果不会,那就别配。”
小林在笔记本上写下:
- 告警要可行动
- 要有阈值和持续时间
- 要分级
- 半夜收到会起来处理的,才配告警
七、排错挑战:概念层面的“排错”
下午,老周给小林出了一道题。
“假设你面试,面试官问你:‘Prometheus 和 Grafana 的区别是什么?’你怎么答?”
小林想了想:“Prometheus 是监控,Grafana 是画图的?”
“太糙了。”老周说,“你再想想。”
小林重新组织语言:“Prometheus 负责采集和存储指标,Grafana 负责把指标可视化展示。Prometheus 是数据源,Grafana 是展示层。”
“好多了。”老周说,“但还差一点。你再想想,Alertmanager 呢?”
“Alertmanager 负责告警……它从 Prometheus 拿告警,然后路由给不同的人。”
“对了。”老周说,“这三个的关系是:Prometheus 是大脑,负责采集、存储、判断;Grafana 是脸,负责展示;Alertmanager 是嘴,负责喊人。”
“这个比喻好。”小林说。
“那你再回答一个问题:为什么不用 Grafana 直接告警,非要 Alertmanager?”
小林想了想:“因为 Grafana 的告警功能比较弱?不支持分组、静默、抑制?”
“对。”老周说,“Grafana 也能告警,但 Alertmanager 更专业。它支持分组(group)、静默(silence)、抑制(inhibit)、路由(route)。你以后工作中,告警基本都用 Alertmanager,Grafana 只负责展示。”
排错思路总结(概念版):
- Prometheus:采集、存储、告警规则判断。
- Grafana:可视化展示。
- Alertmanager:告警路由、分组、静默、抑制。
- 四者关系:exporter 采集 → Prometheus 存储 → Grafana 展示 + Alertmanager 告警。
- 面试回答:先说架构,再说各自职责,最后说为什么这么设计。
“记住,”老周说,“面试问架构,不是让你背名词,是看你理解不理解它们之间的关系。 你把这个图讲清楚,面试官就知道你懂了。”
八、练习
- 练习一:在笔记本或 Markdown 里,画出监控架构图。要求包含:Nginx、node_exporter、Prometheus、Grafana、Alertmanager、QQ 邮箱。标注每个组件的作用和它们之间的数据流向。
- 练习二:用一句话解释以下名词:exporter、Prometheus、Grafana、Alertmanager、metric、Counter、Gauge、拉取模式。
- 练习三:假设你要给博客配三条告警,你会配什么?写出告警条件、阈值、持续时间、告警级别。例如:Nginx 服务挂了,持续 1 分钟,严重告警。
参考答案
练习一:
参考架构图:
node_exporter (9100) ──┐
├──> Prometheus (df -h
输出:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 44G 3.5G 93% /
/dev/sda2 1.0G 100M 900M 10% /boot
tmpfs 2.0G 0 2.0G 0% /dev/shm
“根分区 93% 了。”小林说,“刚才告警是 87%,现在已经 93% 了。涨得这么快?”
他看了一眼时间:凌晨 2 点 20 分。距离告警触发才 7 分钟。
“什么东西涨这么快?”
三、找大目录:du -sh
“老周说过,df 看整体,du 看细节。”小林回忆。
sudo du -sh /* 2>/dev/null | sort -rh | head -10
输出:
12G /var
8.5G /usr
3.2G /home
1.1G /opt
...
“/var 最大,12G。”小林说,“进去看看。”
sudo du -sh /var/* 2>/dev/null | sort -rh | head -10
输出:
10G /var/log
1.2G /var/lib
...
“/var/log 10G。”小林说,“日志怎么这么大?”
sudo du -sh /var/log/* 2>/dev/null | sort -rh | head -10
输出:
8.5G /var/log/nginx
800M /var/log/syslog
300M /var/log/journal
...
“Nginx 日志 8.5G。”小林惊了,“我博客才上线两周,哪来 8.5G 日志?”
sudo ls -lh /var/log/nginx/
输出:
-rw-r----- 1 www-data adm 8.3G Sep 14 02:20 access.log
-rw-r----- 1 www-data adm 200M Sep 14 02:20 error.log
“access.log 8.3G。”小林说,“而且还在涨。”
他看了一眼 error.log,200M,也不小,但跟 access.log 比,小巫见大巫。
四、看日志内容:是什么在刷
“先看看日志里是什么。”小林说。
sudo tail -20 /var/log/nginx/access.log
输出:
192.168.1.100 - - [14/Sep/2026:02:20:01 +0800] "GET /api/health HTTP/1.1" 200 2 "-" "curl/7.81.0"
192.168.1.100 - - [14/Sep/2026:02:20:01 +0800] "GET /api/health HTTP/1.1" 200 2 "-" "curl/7.81.0"
192.168.1.100 - 9090) ──> Grafana (3000)
Nginx (80) ────────────┘ │
│
▼
Alertmanager (9093)
│
▼
QQ 邮箱 (SMTP)
- node_exporter:采集 CPU、内存、磁盘、网络指标。
- Nginx:Web 服务,通过
nginx-prometheus-exporter 或 stub_status 暴露指标。
- Prometheus:拉取指标,存储,执行告警规则。
- Grafana:从 Prometheus 查询数据,可视化。
- Alertmanager:接收 Prometheus 告警,路由到 QQ 邮箱。
练习二:
- exporter:采集指标并暴露 HTTP 接口的程序。
- Prometheus:拉取并存储指标、执行告警规则的监控系统。
- Grafana:从 Prometheus 查询数据并可视化的仪表盘工具。
- Alertmanager:接收 Prometheus 告警,进行路由、分组、静默、抑制。
- metric:指标,包含名称、标签、数值、时间戳。
- Counter:只增不减的指标,关心增长率。
- Gauge:可增可减的指标,关心当前值。
- 拉取模式:Prometheus 主动去 exporter 拉数据,而非 exporter 推送。
练习三:
示例:
- Nginx 服务挂了:
up{job="nginx"} == 0,持续 1 分钟,严重告警,发邮件。
- 磁盘使用率超过 85%:
node_filesystem_avail_bytes / node_filesystem_size_bytes < 0.15,持续 5 分钟,警告告警,发邮件。
- CPU 使用率超过 80%:
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80,持续 5 分钟,警告告警,发邮件。
九、下集预告
监控架构讲清楚了,小林终于知道 exporter、Prometheus、Grafana、Alertmanager 各自是干啥的了。老周说:“明天开始装。先装 node_exporter,让机器学会报告自己的状态。”小林打开终端,准备安装。但他不知道,9100 端口、systemd 服务、指标路径,每一个都可能让他折腾。
下一集:《在 Ubuntu 里请一个“体检医生”:node_exporter》
- [14/Sep/2026:02:20:01 +0800] "GET /api/health HTTP/1.1" 200 2 "-" "curl/7.81.0"
...