个人站长服务器监控与告警系统搭建实战
前言
很多个人站长都有过这样的经历:晚上睡觉前网站还好好的,早上起来发现网站打不开了,数据库挂了,或者硬盘满了,但你已经错过了最佳的恢复时机。服务器监控并不是大公司的专利,个人站长同样可以用免费工具搭建一套可靠的监控告警系统。本文将从零开始,教你用开源工具和简单脚本实现服务器全方位监控。
监控的核心指标
在搭建监控系统之前,需要明确监控什么指标。对于个人站长的 LNMP 环境,重点关注以下四个方面:
系统层面
- CPU 使用率(user/system/iowait)
- 内存使用量(total/used/available)
- 磁盘空间(根分区、数据分区使用率)
- 磁盘 I/O(读写延迟和吞吐量)
- 网络流量(带宽使用率)
应用层面
- Nginx:连接数、请求数、5xx 错误率
- MySQL:慢查询数、连接数、QPS
- PHP-FPM:进程数、空闲/活跃状态
- 系统进程:关键进程是否存活
网络层面
- 外部可用性:网站是否能从外网正常访问
- DNS 解析是否正常
- SSL 证书剩余天数
日志层面
- 系统日志(syslog/rsyslog)
- Nginx 错误日志
- MySQL 错误日志
- 内核日志(dmesg)
方案一:Shell 脚本 + 企业微信/钉钉通知(零成本)
对于预算有限的个人站长,最简单有效的监控方案就是写几个 Shell 脚本,配合免费的消息推送服务。
核心监控脚本
#!/bin/bash
# /usr/local/bin/server_monitor.sh
# 配置
ADMIN_EMAIL="your@email.com"
WEBHOOK_URL="你的企业微信 Bot Webhook URL"
THRESHOLD_DISK=80
THRESHOLD_MEM=90
SITE_URL="https://www.yourdomain.com"
ALERT_LOG="/var/log/server_alert.log"
alert_message=""
# 1. 检查磁盘使用率
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt "$THRESHOLD_DISK" ]; then
alert_message+="磁盘使用率:${DISK_USAGE}%(阈值:${THRESHOLD_DISK}%)\n"
fi
# 2. 检查内存使用率
MEM_USAGE=$(free | awk '/Mem/ {printf("%.0f", $3/$2 * 100)}')
if [ "$MEM_USAGE" -gt "$THRESHOLD_MEM" ]; then
alert_message+="内存使用率:${MEM_USAGE}%(阈值:${THRESHOLD_MEM}%)\n"
fi
# 3. 检查网站可用性
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 --max-time 15 "$SITE_URL")
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "301" ] && [ "$HTTP_CODE" != "302" ]; then
alert_message+="网站无法访问!HTTP状态码:${HTTP_CODE}\n"
fi
# 4. 检查 Nginx 进程
if ! pgrep nginx > /dev/null; then
alert_message+="Nginx 进程未运行!\n"
fi
# 5. 检查 MySQL 进程
if ! pgrep mysqld > /dev/null; then
alert_message+="MySQL 进程未运行!\n"
fi
# 6. 检查 SSL 证书过期(30天内预警)
SSL_EXPIRY=$(echo | openssl s_client -connect ${SITE_URL#https://}:443 -servername ${SITE_URL#https://} 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -n "$SSL_EXPIRY" ]; then
SSL_TS=$(date -d "$SSL_EXPIRY" +%s 2>/dev/null)
NOW_TS=$(date +%s)
DAYS_LEFT=$(( (SSL_TS - NOW_TS) / 86400 ))
if [ "$DAYS_LEFT" -lt 30 ]; then
alert_message+="SSL 证书将在 ${DAYS_LEFT} 天后过期!\n"
fi
fi
# 发送告警
if [ -n "$alert_message" ]; then
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')]\n$alert_message" >> "$ALERT_LOG"
# 企业微信 Bot 通知
curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"【服务器告警】\n$alert_message\"}}" > /dev/null
fi设置 crontab 定时检查
# 每 5 分钟执行一次监控检查
*/5 * * * * /bin/bash /usr/local/bin/server_monitor.sh方案二:Prometheus + Node Exporter + Grafana
如果你想要更专业的监控可视化方案,可以使用 Prometheus 生态。虽然初始配置稍微复杂一些,但部署完成后会非常省心。
安装 Node Exporter
# 下载 Node Exporter
wget https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-linux-amd64.tar.gz
tar xzf node_exporter-linux-amd64.tar.gz
sudo mv node_exporter-linux-amd64/node_exporter /usr/local/bin/
# 创建 systemd 服务
cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=nobody
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now node_exporter安装 Prometheus
# 下载 Prometheus
wget https://github.com/prometheus/prometheus/releases/latest/download/prometheus-linux-amd64.tar.gz
tar xzf prometheus-linux-amd64.tar.gz
sudo mv prometheus-linux-amd64 /opt/prometheus配置 Prometheus,添加监控目标:
# /opt/prometheus/prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']对于个人站长来说,Prometheus 本身占用的资源很少(约 100MB 内存),即使和网站跑在同一台服务器上也不会影响性能。
安装 Grafana
# Debian/Ubuntu 安装
sudo apt-get install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_11.0.0_amd64.deb
sudo dpkg -i grafana_11.0.0_amd64.deb
sudo systemctl enable --now grafana-serverGrafana 默认运行在 3000 端口。登录后添加 Prometheus 数据源,然后导入 Node Exporter Full 仪表盘(ID:1860),即可看到完整的系统监控面板。
方案三:安装 Uptime Kuma 监控网站可用性
除了服务器内部的性能监控,还需要从外部检测网站是否可访问。Uptime Kuma 是一个开源的 uptime 监控工具,界面美观,支持多种通知方式。
# 使用 Docker 安装(推荐)
docker run -d --restart=always \
-p 3001:3001 \
-v uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma:latestUptime Kuma 的配置非常直观:
- 访问 http://你的IP:3001,创建管理员账号
- 添加监控项:输入网站 URL,设置检查间隔(建议 60 秒)
- 配置通知:支持企业微信、钉钉、Telegram、邮件等数十种通知方式
设置告警通知
企业微信 Bot
在企微群里添加机器人,获取 Webhook URL:
curl -X POST "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY" \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"告警信息"}}'钉钉 Bot
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=你的TOKEN" \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"告警信息"}}'Telegram Bot
curl -s "https://api.telegram.org/bot你的TOKEN/sendMessage" \
-d "chat_id=你的CHAT_ID&text=告警信息"实战经验与避坑指南
不要过度告警
这是新手站长最容易犯的错误。阈值设得太低会导致告警轰炸,最终形成告警疲劳。建议:
- CPU 使用率:90% 持续 5 分钟以上再告警
- 内存使用率:90% 以上再告警
- 磁盘使用率:80% 警告,90% 紧急
- 网站可用性:连续 2 次检查失败再告警
用 Python 脚本做一个简单的去重逻辑,15 分钟内相同告警不重复发送。
磁盘空间监控要排除特殊目录
# 不要监控这些目录
# /proc, /sys, /dev, /run 都是虚拟文件系统
df -h --exclude-type=tmpfs --exclude-type=devtmpfs日志轮转避免磁盘爆满
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}总结
服务器监控是个人站长容易忽视但至关重要的工作。从最简单的 Shell 脚本 + 消息推送,到 Prometheus + Grafana 专业方案,再到 Uptime Kuma 外部监控,你可以根据自己的需求和预算选择适合的方案。我的建议是:先用脚本方案快速搭建基础监控,等网站流量大了再升级到 Prometheus + Grafana。最重要的是把监控跑起来,而不是追求完美的监控架构。记住,没有监控的系统就像没有仪表盘的飞机,看起来在飞,但你不知道什么时候会出问题。