我给自己的服务器配了一套监控告警,几个关键节点说清楚
事情是这样的:上个月有台 VPS 突然挂了,我在外面吃饭,完全不知道。等回到家发现网站已经挂了两个多小时。用户群里有人问"网站是不是打不开了",我才知道出事了。
登录一看,CPU 被某个进程吃满了。问题是这玩意要是白天挂也就算了,偏偏挑我不在的时候挂。从那以后我就下了决心——服务器必须得有监控告警,不能靠人肉盯。
现在配好了:CPU 超 80% 钉钉弹消息,磁盘快满了微信提醒。跑了一个多月,挺稳。写一下我是怎么搞的。
我选的方案:Prometheus + Node Exporter + Grafana
市面上监控方案很多,Zabbix、Nagios、Datadog、阿里云监控……我的选择标准就两条:
- 免费 — 个人项目,不想为监控再花钱
- 轻量 — 不会给本来就 2G 内存的 VPS 加负担
最后定了 Prometheus 全家桶:
- Node Exporter — 装在服务器上,暴露 CPU、内存、磁盘、网络这些指标
- Prometheus — 定时去抓 Node Exporter 的数据,存起来
- Grafana — 把 Prometheus 的数据画成好看的图表
- Alertmanager — 触发告警,推送到钉钉/微信/邮件
它们之间的关系大概是这样:
服务器 (Node Exporter) ──→ Prometheus ──→ Grafana (看板)
└──→ Alertmanager → 钉钉/微信 (告警)
第一步:装 Node Exporter
Node Exporter 是最简单的一步。它是 Go 写的,就一个二进制文件,不依赖任何东西。
# 下载
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
sudo mv node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
# 配 systemd 让它开机自启
sudo tee /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
验证一下:
curl http://localhost:9100/metrics
能看到一堆 node_cpu_seconds_total、node_memory_MemAvailable_bytes 就对了。9100 是默认端口。
如果你的服务器有公网 IP,建议用 iptables 或者 nginx 把 9100 端口限制一下,只允许 Prometheus 那台机器访问。我不在这里展开,但这是个安全隐患——默认谁都能访问你的 metrics。
第二步:装 Prometheus
Prometheus 我装在另一台机器上(也可以跟 Node Exporter 同一台,看你资源够不够)。
wget https://github.com/prometheus/prometheus/releases/download/v2.55.1/prometheus-2.55.1.linux-amd64.tar.gz
tar xzf prometheus-2.55.1.linux-amd64.tar.gz
sudo mv prometheus-2.55.1.linux-amd64 /opt/prometheus
编辑配置文件 /opt/prometheus/prometheus.yml:
global:
scrape_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- "alerts.yml"
scrape_configs:
- job_name: 'vps'
static_configs:
- targets: ['你的服务器IP:9100']
scrape_interval: 15s 意思是每 15 秒抓一次指标。个人项目这个频率够了,不用设太密。
配 systemd:
sudo tee /etc/systemd/system/prometheus.service <<EOF
[Unit]
Description=Prometheus
After=network.target
[Service]
ExecStart=/opt/prometheus/prometheus \
--config.file=/opt/prometheus/prometheus.yml \
--storage.tsdb.path=/opt/prometheus/data
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
Prometheus 默认跑在 9090 端口。打开 http://你的IP:9090 能看到一个很朴素的界面——先别嫌弃,图表我们交给 Grafana 来画。
第三步:装 Grafana,这才是看数据的界面
Prometheus 自带的图表……说实话不好看。Grafana 才是那个让你眼前一亮的东西。
# Ubuntu/Debian
sudo apt-get install -y software-properties-common
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install -y grafana
sudo systemctl enable --now grafana-server
默认跑在 3000 端口。浏览器打开 http://IP:3000,默认账号密码都是 admin。
进去以后三步:
- 添加数据源 → 选 Prometheus → URL 填
http://localhost:9090 - 导入看板模板 → Dashboard → Import → 输入
1860(这是社区最流行的 Node Exporter 看板 ID) - 选刚才加的 Prometheus 数据源,点 Import
然后你就能看到 CPU、内存、磁盘、网络流量全在一页上,效果大概是这样的(CPU 那根线突然飙高的时候真的有一种"幸好我装了监控"的感觉)。
第四步:配告警规则
有监控没告警等于没监控。我不可能整天盯着 Grafana 看。
编辑 /opt/prometheus/alerts.yml:
groups:
- name: server_alerts
rules:
- alert: CpuHigh
expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU 使用率超过 80%"
description: "服务器 {{ $labels.instance }} 的 CPU 使用率已经超过 80%,持续 5 分钟了"
- alert: DiskAlmostFull
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100 < 10
for: 1m
labels:
severity: critical
annotations:
summary: "磁盘空间不足 10%"
description: "{{ $labels.instance }} 的 {{ $labels.mountpoint }} 只剩 {{ $value }}% 空间了"
- alert: MemoryHigh
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: warning
annotations:
summary: "内存使用超过 90%"
description: "服务器 {{ $labels.instance }} 内存快满了"
三条规则的逻辑:
- CPU 用
rate()算 5 分钟平均值,超过 80% 且持续 5 分钟才告警(防瞬间毛刺) - 磁盘直接看剩余比例,低于 10% 马上告警(这个不能等)
- 内存超过 90% 持续 5 分钟告警
第五步:告警推送到钉钉
Alertmanager 负责把告警发出去。先装:
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xzf alertmanager-0.27.0.linux-amd64.tar.gz
sudo mv alertmanager-0.27.0.linux-amd64 /opt/alertmanager
编辑 /opt/alertmanager/alertmanager.yml:
global:
resolve_timeout: 5m
route:
receiver: 'dingtalk'
receivers:
- name: 'dingtalk'
webhook_configs:
- url: 'https://oapi.dingtalk.com/robot/send?access_token=你的token'
send_resolved: true
钉钉机器人的 webhook 地址去钉钉群 → 群设置 → 智能群助手 → 添加机器人 → 自定义,拿到 webhook URL 填上去就行。
用微信也差不多,换成企业微信机器人的 webhook;用飞书也行,逻辑一样。不想配这些的话也可以用最原始的邮件告警,Alertmanager 也支持。
配完 systemd,启动:
sudo tee /etc/systemd/system/alertmanager.service <<EOF
[Unit]
Description=Alertmanager
After=network.target
[Service]
ExecStart=/opt/alertmanager/alertmanager --config.file=/opt/alertmanager/alertmanager.yml
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager
我踩过的几个坑
坑一:Prometheus 自己的存储会膨胀
Prometheus 默认每 15 秒抓一次,数据全存本地。跑了两个月我一看,/opt/prometheus/data 占了快 3G。
解决办法:在启动参数里加两个限制:
--storage.tsdb.retention.time=30d # 只保留 30 天数据
--storage.tsdb.retention.size=2GB # 最多占 2G
个人项目 30 天足够,不需要保留一年的监控数据。
坑二:Node Exporter 暴露了太多东西
localhost:9100/metrics 暴露的信息其实挺敏感的——别人能看到你服务器上跑了什么进程、开了哪些端口。如果 Prometheus 和 Node Exporter 不在同一台机器上,务必把 9100 端口用防火墙限制 IP 访问。
坑三:告警风暴
我第一次配告警的时候没考虑好,CPU 一超 80% 就开始叮叮叮地发消息。不到十分钟钉钉群被刷屏了。
解决办法是 Alertmanager 的 group_by 和 group_interval 参数,把相同类型的告警合并成一条发:
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 5m
repeat_interval: 1h
这样同一个告警一小时内最多发一次,不会刷屏。
花了多少资源
整套在 2G 内存的 VPS 上的资源占用:
| 组件 | 内存 |
|---|---|
| Node Exporter | ~15MB |
| Prometheus | ~200MB |
| Grafana | ~80MB |
| Alertmanager | ~20MB |
| 合计 | ~315MB |
对个人 VPS 来说完全可接受。如果 Prometheus 和 Grafana 都装在同一台机器上,大概 300MB 多一点。如果你只有一台机器,也可以把 Prometheus 的数据保留时间设短点(15 天或者 7 天),省点磁盘。
小结
从零配完大概一个下午。时间主要花在 Prometheus 和 Alertmanager 的配置文件上,第一次写很容易少个缩进或者写错端口。照着上面的步骤一步步来,能少走不少弯路。
装完以后最大的感受:以前出门老惦记服务器,现在钉钉不响就没事。这种"不用盯着也知道没事"的感觉,真的很好。
Node Exporter 完整指标列表:https://github.com/prometheus/node_exporter#enabled-by-default
Grafana Dashboard 1860:https://grafana.com/grafana/dashboards/1860-node-exporter-full/
评论 (0)