VPS 管理员最常见的错误之一,就是在服务器出现问题造成损失之后才发现异常。CPU 跑满 100% 导致应用响应迟缓、内存耗尽引发进程被强制终止、磁盘写满使数据库无法写入——这些问题只要配置了正确的监控警报,都是完全可以预防的。主动预防故障与被动响应宕机的关键区别,在于是否拥有一套能在问题失控之前提前通知您的警报系统。
本指南将带您从零开始在 Linux VPS 上搭建完整的警报系统:选择合适的工具、配置阈值、通过 Telegram 和邮件发送通知,并验证整个流程是否正常运行。示例涵盖 CPU、内存、磁盘和服务可用性,适用于运行 WordPress、Node.js、Docker 或企业应用的任何 VPS。
监控与警报:为何两者缺一不可
许多 VPS 管理员搭建了漂亮的 Grafana 实时仪表盘,显示 CPU 和内存图表,但凌晨 3 点出现问题时没有人盯着屏幕,仪表盘便毫无用处。一套好的警报系统相当于您全天候驻守服务器的"眼睛"。
- 监控(Monitoring) — 持续采集 CPU 使用率、内存占用、I/O 吞吐量等指标,并存储历史数据以供趋势分析。
- 警报(Alerting) — 将指标与预设阈值进行比较,超限时通过您选择的渠道发送通知。
- 两者结合 — 监控告诉您发生了什么;警报告诉您现在需要关注什么。
举个实际例子:晚上 8 点磁盘使用率达到 90%。没有警报,您可能要到第二天早上才发现。有了警报,手机立刻收到 Telegram 消息。您 SSH 登入服务器,清理旧日志文件,磁盘使用率降回 60%,数据库从未中断写入。零停机,零数据丢失。
为 VPS 选择合适的警报工具
Linux VPS 监控与警报有多种成熟方案可选,最佳选择取决于您管理的服务器数量以及所需的灵活程度。
| 工具 | 复杂度 | 适用场景 | 通知方式 |
|---|---|---|---|
| Netdata | 简单 | 单台 VPS、快速上手 | Email、Telegram、Slack、PagerDuty |
| Prometheus + Alertmanager | 中–高 | 多台服务器、自定义应用指标 | Email、Telegram、Webhook、PagerDuty |
| Zabbix | 高 | 企业级、大型基础设施 | Email、短信、Webhook |
| Shell 脚本 + Cron | 简单(自制) | 无需额外软件的定向警报 | Email、Telegram、Line Notify |
对于典型的 Ubuntu/Debian VPS,建议从 Netdata 入手——一条命令即可安装集监控、警报和内置仪表盘于一体的完整套件。当您需要完全掌控或管理多台服务器时,再迁移到 Prometheus。
安装 Netdata 并配置 Telegram 警报
Netdata 是从零开始搭建可用警报系统的最快路径。它默认采集超过一千个指标,提供实时仪表盘,并且无需任何外部数据库或额外组件即可触发警报。
安装 Netdata
wget -O /tmp/netdata-kickstart.sh https://my-netdata.io/kickstart.sh sudo bash /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry
安装完成后,Netdata 运行于 http://your-vps-ip:19999。请配置防火墙规则限制访问,避免公开暴露。
配置 Telegram 通知
编辑 /etc/netdata/health_alarm_notify.conf:
SEND_TELEGRAM="YES" TELEGRAM_BOT_TOKEN="YOUR_BOT_TOKEN_HERE" TELEGRAM_CHAT_ID="YOUR_CHAT_ID_HERE" DEFAULT_RECIPIENT_TELEGRAM="YOUR_CHAT_ID_HERE"
自定义 CPU 警报阈值
警报规则存放在 /etc/netdata/health.d/ 中。创建自定义 CPU 规则:
# /etc/netdata/health.d/cpu-custom.conf alarm: cpu_usage_warning on: system.cpu lookup: average -15m unaligned of user,system,softirq,irq,guest units: % every: 1m warn: $this > 80 crit: $this > 90 delay: down 15m multiplier 1.5 max 1h info: CPU usage exceeds defined threshold to: sysadmin
无需重启即可重新加载:
sudo kill -USR2 $(pidof netdata)
使用 Prometheus + Alertmanager 实现高级警报
如果您需要对警报路由、抑制、静默和分组进行精细控制,或者需要管理多台服务器,Prometheus 与 Alertmanager 是行业标准方案。配置步骤较多,但灵活性大幅提升。
安装 Node Exporter 采集系统指标
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz tar xf node_exporter-1.7.0.linux-amd64.tar.gz sudo mv node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/ sudo tee /etc/systemd/system/node_exporter.service <<'EOF' [Unit] Description=Node Exporter After=network.target [Service] User=node_exporter ExecStart=/usr/local/bin/node_exporter Restart=on-failure [Install] WantedBy=multi-user.target EOF sudo useradd -rs /bin/false node_exporter sudo systemctl enable --now node_exporter
内存与磁盘警报规则
# /etc/prometheus/rules/server_alerts.yml
groups:
- name: server_alerts
rules:
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85
for: 5m
labels:
severity: warning
annotations:
summary: "High memory on {{ $labels.instance }}"
description: "Memory used: {{ printf \"%.1f\" $value }}%"
- alert: DiskSpaceLow
expr: (1 - (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"})) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Low disk space on {{ $labels.instance }}"
description: "{{ $labels.mountpoint }} is {{ printf \"%.1f\" $value }}% full"
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} is down"
description: "{{ $labels.instance }} has been unreachable for 1 minute"
配置 Alertmanager 通过 Telegram 发送通知
在 Prometheus 中定义好警报规则后,配置 Alertmanager 将通知路由到 Telegram:
# /etc/alertmanager/alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'instance']
group_wait: 30s
group_interval: 5m
repeat_interval: 3h
receiver: 'telegram-notifications'
receivers:
- name: 'telegram-notifications'
telegram_configs:
- bot_token: 'YOUR_BOT_TOKEN'
chat_id: YOUR_CHAT_ID
parse_mode: 'HTML'
message: |
<b>{{ .Status | toUpper }}</b> - {{ .GroupLabels.alertname }}
{{ range .Alerts }}
<b>Instance:</b> {{ .Labels.instance }}
<b>Details:</b> {{ .Annotations.description }}
{{ end }}
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']
inhibit_rules 部分用于在同一实例已触发严重警报时,抑制重复的警告级别通知——这是减少生产环境警报疲劳的关键功能。
使用 Shell 脚本与 Cron 实现最简警报
如果您不想安装任何额外软件,一个简单的 Shell 脚本结合 Cron 即可针对最关键的阈值提供有效警报。这种方式完全自给自足,易于理解。
#!/bin/bash
# /opt/monitor/check_resources.sh
TELEGRAM_TOKEN="YOUR_BOT_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
HOSTNAME=$(hostname)
send_alert() {
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d parse_mode="HTML" \
-d text="$1" >/dev/null
}
# CPU check (5-minute load average vs core count)
CPU_LOAD=$(awk '{print $1}' /proc/loadavg)
CPU_CORES=$(nproc)
CPU_PERCENT=$(echo "scale=0; $CPU_LOAD * 100 / $CPU_CORES" | bc)
[ "$CPU_PERCENT" -gt 90 ] && send_alert "🔴 <b>[CRITICAL] CPU</b> - ${HOSTNAME}: ${CPU_PERCENT}%"
[ "$CPU_PERCENT" -gt 80 ] && [ "$CPU_PERCENT" -le 90 ] && \
send_alert "🟡 <b>[WARNING] CPU</b> - ${HOSTNAME}: ${CPU_PERCENT}%"
# Memory check
MEM_TOTAL=$(grep MemTotal /proc/meminfo | awk '{print $2}')
MEM_AVAIL=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
MEM_PCT=$(echo "scale=0; (($MEM_TOTAL - $MEM_AVAIL) * 100) / $MEM_TOTAL" | bc)
[ "$MEM_PCT" -gt 90 ] && send_alert "🔴 <b>[CRITICAL] Memory</b> - ${HOSTNAME}: ${MEM_PCT}%"
[ "$MEM_PCT" -gt 80 ] && [ "$MEM_PCT" -le 90 ] && \
send_alert "🟡 <b>[WARNING] Memory</b> - ${HOSTNAME}: ${MEM_PCT}%"
# Disk check
DISK_PCT=$(df / | awk 'NR==2{print $5}' | sed 's/%//')
[ "$DISK_PCT" -gt 90 ] && send_alert "🔴 <b>[CRITICAL] Disk</b> - ${HOSTNAME}: ${DISK_PCT}%"
[ "$DISK_PCT" -gt 80 ] && [ "$DISK_PCT" -le 90 ] && \
send_alert "🟡 <b>[WARNING] Disk</b> - ${HOSTNAME}: ${DISK_PCT}%"
使用 Cron 设置每 5 分钟检查一次:
chmod +x /opt/monitor/check_resources.sh crontab -e # Add: */5 * * * * /opt/monitor/check_resources.sh
防止警报疲劳:如果 CPU 持续高负载数小时,每 5 分钟运行一次的脚本会发送数十条消息将您淹没。可以添加带冷却期的锁文件:if [ ! -f /tmp/cpu_alert ] || [ $(( $(date +%s) - $(stat -c %Y /tmp/cpu_alert) )) -gt 3600 ]; then send_alert "..."; touch /tmp/cpu_alert; fi——这样可确保在条件未解除前,同一警报每小时最多触发一次。
每台生产 VPS 必备的警报清单
无论选择哪种工具,以下警报都应在每台承载真实流量的 VPS 上保持启用:
系统资源警报
- CPU 使用率 — 15 分钟平均值超过 80%(警告),超过 90%(严重)
- 内存使用率 — RAM 占用超过 85%(警告),超过 95%(严重)
- 磁盘空间 — 根分区或数据分区超过 80%(警告),超过 90%(严重)
- 磁盘 I/O 等待 — 持续高 I/O 等待可能预示磁盘即将故障
- Swap 使用率 — Swap 超过 50% 表示内存不足,考虑升级配置
服务可用性警报
- Web 服务器宕机 — nginx 或 Apache 无响应(HTTP 5xx 或连接被拒绝)
- 数据库不可达 — MySQL 或 PostgreSQL 无法接受连接
- 应用进程缺失 — Node.js 或 PHP-FPM 进程已停止运行
- SSL 证书即将到期 — 证书在 14 天内到期
安全警报
- SSH 多次登录失败 — 正在遭受暴力破解攻击
- Root 账户登录成功 — 有人从未知 IP 以 root 身份成功登录
- 异常出站流量 — 可能已被入侵或有挖矿程序在运行
在正式依赖之前测试您的警报系统
一个静默失败的错误配置警报系统比没有警报更糟糕——它会制造虚假的安全感。在将系统用于生产工作负载之前,务必进行端到端测试。
测试 Telegram 连通性
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="✅ Alert system test from $(hostname) - OK"
模拟高 CPU 负载
sudo apt install stress-ng -y stress-ng --cpu 4 --timeout 300s & # Wait 5–15 minutes for alerts to fire based on your configured duration # Stop the test: kill %1
检查 Alertmanager 和 Netdata 日志
# Alertmanager sudo journalctl -u alertmanager -f # Netdata health log tail -f /var/log/netdata/health.log
常见问题(FAQ)
CPU 警报应该设置多少阈值?
对于通用服务器,警告阈值设为 80%、严重阈值设为 90% 通常效果较好。建议测量 5–15 分钟的平均值而非瞬时峰值,因为短暂的 CPU 突发是正常现象。如果收到过多警报(警报疲劳),可先将持续时间延长到 10 分钟,再考虑调整阈值。最终根据实际工作负载模式随时间进行微调。
Netdata 与 Prometheus Alertmanager 有何区别?
Netdata 适合只有单台 VPS 且需要一个工具同时提供实时仪表盘和警报的场景——一条命令即可安装并立即运行。Prometheus 加 Alertmanager 适合多服务器环境或需要自定义应用指标的场景,灵活性更高但配置也更复杂。对于刚起步的独立 VPS,Netdata 开箱即用价值更高。
CPU 很高时为什么警报没有发送?
常见原因包括:通知渠道配置错误(Telegram Bot Token 或 Chat ID 有误)、告警规则语法错误导致 Alertmanager 无法加载规则文件、防火墙在 443 端口屏蔽了出站网络,或警报意外处于 Inhibit 或 Silence 状态。请检查 Alertmanager 日志,并在生产环境依赖该系统之前使用 amtool alert add 进行测试。
如何通过 Telegram 机器人发送 VPS 警报?
通过 Telegram 上的 @BotFather 创建机器人并获取 API Token,然后将机器人添加到您希望接收通知的群组或聊天。发送消息后调用 https://api.telegram.org/bot<TOKEN>/getUpdates 获取 Chat ID。在 Alertmanager 接收器或 Netdata 通知设置中填入 Token 和 chat_id 值。部署到生产环境之前务必用 curl 请求验证连接是否正常。
AsiaGB 高性能 KVM VPS
AsiaGB VPS 提供完整 Root 权限,支持 Docker、MySQL、Python 和 Node.js,套餐价格低至每月 500 泰铢。
查看 VPS 套餐