本文约 6,675 字,预计阅读 17 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:最尴尬的是客户比你还先发现网站挂了
大部分个人站长和中小企业网站的运维状态是”被动发现”:网站挂了 → 客户或同事发消息 → 自己打开看看 → 登录服务器查日志 → 重启服务。从故障发生到你开始处理,中间可能已经过去两三个小时,如果是凌晨宕机,可能要等到第二天早上。
更常见的不是”完全宕机”而是”半死不活”:PHP-FPM 进程打满导致响应 30 秒、磁盘写满导致无法上传图片、SSL 证书过期、备份任务连续一周失败、MySQL 慢查询拖垮全站。这些状态传统 ping 检测发现不了,等发现时已经是数据丢失或流量损失。
一套够用的监控体系不需要很复杂:一个拨测服务检查”能不能访问”+ 一个 Agent 采集”机器状态如何”+ 一条能真正送达的通知链路。自建成本约等于一台 1 核 2 G 的小机器,或者干脆零成本用云厂商的免费额度。
原理分析:监控的三个层次与两类指标
第一层:黑盒监控(Black-box,从外部看)。 模拟真实用户发起 HTTP 请求,检查状态码、响应时间、页面关键字。这是最贴近用户体验的监控,能发现”完全打不开””502″”响应极慢”。代表工具:Uptime Kuma、UptimeRobot、云厂商的站点监控。
第二层:白盒监控(White-box,从内部看)。 在服务器上安装 Agent 采集 CPU、内存、磁盘、网络、进程状态。能发现”CPU 跑满””磁盘将满””MySQL 挂了”。代表工具:Node Exporter + Prometheus + Grafana、云厂商的 CloudMonitor Agent、Netdata。
第三层:业务监控。 检查”业务是否正常”,比如:备份任务是否成功执行、SSL 证书还有几天到期、WordPress 的 WP-Cron 是否正常触发、订单表是否长时间无新数据。这一层最容易被忽略,但往往最致命——备份失败三个月没人知道,直到需要恢复那天才发现备份文件是空的。
两类指标的取舍。 监控数据分 Counter(累计值,如总请求数)和 Gauge(瞬时值,如当前内存使用率)。告警规则应基于 Gauge 加”持续时间”条件,避免瞬时抖动误报。比如”CPU > 80%”应该写成”CPU > 80% 持续 5 分钟”,否则一次备份任务就会触发告警。
告警疲劳是监控失效的头号原因。 一个每天发 20 条告警的系统,一周后就会被设置成免打扰,等于没有监控。设计原则是:只对”需要人立刻处理的事”告警,其余的做成报表。
保姆级实操:半小时搭一套可用体系
步骤 1:用 Docker 部署 Uptime Kuma 做拨测。 这是目前自建监控里最容易上手的一个,单容器、带 Web 界面、支持多种通知渠道。
# 安装 Docker(Ubuntu)
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now docker
# 启动 Uptime Kuma
docker run -d --restart=always \
-p 3001:3001 \
-v uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma:1
访问 http://你的IP:3001 完成初始化,创建管理员账号。务必用一个反向代理加 HTTPS 和强密码,这个面板暴露在公网会有风险:
server {
listen 443 ssl;
http2 on;
server_name status.mimangfei.com;
ssl_certificate /etc/nginx/ssl/mimangfei.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/mimangfei.com/key.pem;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 支持 Kuma 的 WebSocket 推送
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
步骤 2:添加监控项。 至少要覆盖这几类:
| 监控项 | 类型 | 建议间隔 | 告警阈值 |
|---|---|---|---|
| 首页 HTTP(S) | HTTP(s) | 60 秒 | 状态码非 200 或响应 > 5 秒 |
| 首页关键字 | HTTP(s) – Keyword | 300 秒 | 页面不含”站点名称”即告警 |
| SSL 证书到期 | 自动检测 | 每天 | 剩余 < 14 天告警 |
| 服务器 SSH/TCP 端口 | TCP Port | 60 秒 | 端口不通即告警 |
| 数据库端口 | TCP Port | 60 秒 | 端口不通即告警 |
| 备份文件更新 | HTTP(s) / 自定义脚本 | 每天 | 备份文件超过 26 小时未更新告警 |
关键字监控很重要:站点被挂马或被劫持时,状态码可能仍是 200,但页面内容已经变了。检测首页是否包含固定文案能发现这类问题。
步骤 3:配置多渠道通知。 Uptime Kuma 支持 Telegram、企业微信机器人、钉钉、飞书、Webhook、SMTP 等。国内推荐用 PushPlus(微信公众号推送,免费额度够用)或企业微信群机器人:
# 测试企业微信机器人 webhook(把 KEY 换成你自己的)
curl -s -X POST \
'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY' \
-H 'Content-Type: application/json' \
-d '{
"msgtype": "text",
"text": {
"content": "[告警] mimangfei.com 首页不可访问\n状态: DOWN\n时间: 2026-10-10 03:21:00",
"mentioned_mobile_list": ["13800138000"]
}
}'
在 Uptime Kuma 的通知设置里选择 Webhook,填入上面的地址,Body 用 JSON 并把 {{msg}} 变量放进 content 字段即可。
步骤 4:安装服务器资源采集(轻量级方案)。 如果觉得 Prometheus + Grafana 太重,用 Netdata 单机版最快:
# 一键安装 Netdata(自带 Web 面板,默认 19999 端口)
bash <(curl -Ss https://my-netdata.io/kickstart.sh) --stable-channel
# 只监听本地,通过 Nginx 反代访问,避免公网暴露
sudo nano /etc/netdata/netdata.conf
[web]
bind to = 127.0.0.1
sudo systemctl restart netdata
步骤 5:写自定义检查脚本,覆盖业务层监控。 这是 Uptime Kuma 和 Netdata 都覆盖不到的部分,用脚本 + cron 实现:
#!/usr/bin/env bash
# /opt/scripts/check_site.sh —— 业务健康自检,每天 8:00 由 cron 执行
set -uo pipefail
SITE="https://www.mimangfei.com"
BACKUP_DIR="/backup/wordpress"
WEBHOOK="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"
MSG=""
alert() {
curl -s -X POST "$WEBHOOK" -H 'Content-Type: application/json' \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"[站点自检告警]\n$1\"}}" >/dev/null
}
# 1. 检查首页状态码与响应耗时
code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 "$SITE")
cost=$(curl -s -o /dev/null -w '%{time_total}' --max-time 10 "$SITE")
if [ "$code" != "200" ]; then
MSG="${MSG}首页返回 ${code}\n"
elif (( $(echo "$cost > 5" | bc -l) )); then
MSG="${MSG}首页响应过慢: ${cost}s\n"
fi
# 2. 检查备份文件是否在 26 小时内更新过
latest=$(find "$BACKUP_DIR" -name '*.sql.gz' -mmin -1560 2>/dev/null | wc -l)
if [ "$latest" -eq 0 ]; then
MSG="${MSG}26 小时内无新备份文件\n"
fi
# 3. 检查磁盘使用率是否超过 85%
usage=$(df -P / | awk 'NR==2 {print $5}' | tr -d '%')
if [ "$usage" -gt 85 ]; then
MSG="${MSG}根分区已用 ${usage}%\n"
fi
# 4. 检查证书剩余天数
days=$(echo | openssl s_client -connect www.mimangfei.com:443 -servername www.mimangfei.com 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
days_left=$(( ( $(date -d "$days" +%s) - $(date +%s) ) / 86400 ))
if [ "$days_left" -lt 14 ]; then
MSG="${MSG}SSL 证书仅剩 ${days_left} 天\n"
fi
[ -n "$MSG" ] && alert "$MSG"
exit 0
sudo chmod +x /opt/scripts/check_site.sh
# 加入 crontab,每天 8 点执行
echo "0 8 * * * /opt/scripts/check_site.sh >> /var/log/site_check.log 2>&1" | sudo tee /etc/cron.d/site-check
步骤 6:故障发生后的自动自救。 对于”PHP-FPM 挂了””MySQL 意外退出”这类可自愈的故障,配置自动重启比等人来处理更实际:
# 用 systemd 的自动重启能力,给 PHP-FPM 和 MySQL 加上自动拉起
sudo mkdir -p /etc/systemd/system/php8.2-fpm.service.d
sudo tee /etc/systemd/system/php8.2-fpm.service.d/restart.conf > /dev/null <<'EOF'
[Service]
Restart=on-failure
RestartSec=5s
StartLimitBurst=5
EOF
sudo systemctl daemon-reload
sudo systemctl restart php8.2-fpm
步骤 7:告警降噪。 配置”连续 N 次失败才告警”和”恢复通知”,避免抖动刷屏:在 Uptime Kuma 的监控项里把 “Retries” 设为 2–3,同时开启 “Resend Notification if Down X times”,重要站点每 10 次重发一次。
常见踩坑
- 监控服务和被监控站点放在同一台机器上。 机器宕机时监控一起挂,告警永远发不出来。监控机必须异地部署,至少用云厂商的免费拨测作为第二路。
- 只监控 ping 不监控 HTTP。 ICMP 通不代表 80 端口正常,更不代表 PHP 和 MySQL 正常。必须做 HTTP 状态码 + 关键字检测。
- 告警太多导致麻木。 只保留”需要立刻处理”的告警,其他做成周报。
- 忘了监控”备份是否成功”。 这是最典型的第三层盲区,脚本里的第 2 项就是为此。
- cron 里的 PATH 问题导致脚本静默失败。 上面的脚本里
openssl、bc、curl都用了绝对路径或确保 PATH 正确,cron 环境的 PATH 只有/usr/bin:/bin。 - 监控面板暴露在公网且用弱密码。 Uptime Kuma 面板能看到你所有站点的状态,务必上 HTTPS + 强密码,或者用 IP 白名单限制。
- 案例:一次”监控正常但网站打不开”。 客户配置了对
mimangfei.com的 HTTP 监控,一切正常,但客户反映网站打不开。排查发现监控用的是根域名,而用户访问的是www.mimangfei.com,www的 DNS 记录在迁移时忘了添加。教训:监控要覆盖用户真正访问的 URL,包括 www 和非 www、http 和 https 四种组合,并且定期(比如每次改版后)核对监控项与实际入口是否一致。这点和 网站改版 URL 映射 里说的入口梳理是同一件事。
总结
监控体系的判断标准是”故障发生后,你比用户先知道”。落地顺序:先部署 Uptime Kuma 做 HTTP + 关键字拨测(异地部署)→ 配好多渠道通知 → 加 Netdata 看资源趋势 → 写自定义脚本覆盖证书、备份、磁盘 → systemd 自动重启做自救 → 最后做告警降噪。上线前把 网站上线安全基线配置 里提到的 ss -lntp、磁盘、进程检查也纳入定期自检脚本。记住:监控本身也要被监控——每周确认一次告警通道是否还通,别让”监控静默失效”成为新的盲区。
