想自动监控服务器宕机并发送邮件提醒吗?一份零基础也能上手的实战指南
📖 目录导读
- 为什么你需要服务器宕机监控?
- 常见的监控方案对比(免费 vs 付费)
- 手把手搭建:用Python + Shell实现7x24小时宕机检测
- 邮件报警配置(QQ/163/Gmail/SMTP全支持)
- 进阶:多服务器、多策略、告警收敛
- 常见问题与优化技巧(避免误报、支持国内网络)
❓ 问答速查
- Q: 宕机检测脚本多久执行一次合适? A: 建议1-5分钟一次,过短会增加服务器压力(尤其API调用),过长则无法及时发现问题,推荐使用3分钟间隔。
- Q: 如果监控服务器自己挂了怎么办? A: 建议两台独立服务器互监,或使用第三方免费监控(如UptimeRobot)作为保底。
- Q: 脚本一直运行会不会很占资源? A: 一个简单的ping脚本仅占用不到5MB内存,几乎不影响业务服务器运行。
为什么你需要自动监控?
服务器宕机带来的损失远比你想象的大:

- 电商网站:每宕机1分钟可能损失数万元订单
- API服务:客户端持续重试可能导致雪崩
- 公司内网:FTP/数据库不可用,全员停摆
手动监控?你不可能24小时盯着屏幕,更不可能每次都在第一时间收到通知,而一套自动宕机监控+邮件报警系统,可以让你在故障发生3分钟内知道问题,哪怕你在睡觉、出差、甚至度假。
监控方案对比
| 方案 | 成本 | 难度 | 优点 | 缺点 |
|---|---|---|---|---|
| Zabbix | 免费 | 高(需部署服务端) | 功能强大,支持自定义 | 配置复杂,维护成本高 |
| Prometheus + Alertmanager | 免费 | 中高 | 适合容器/微服务 | 需要技术基础 |
| 自写脚本(本文方案) | 免费 | 低 | 灵活、轻量、可控 | 需要简单编程基础 |
| UptimeRobot | 免费(50个) | 零 | 无需服务器 | 国外节点可能不稳定 |
| 付费监控(如新睿云) | 50-100元/月 | 零 | 省心、短信提醒 | 长期成本较高 |
对于中小企业或个人站长,自写脚本是性价比最高的选择。 下面我将给出一个可以直接复制粘贴的脚本,你只需要改三个地方就能用。
手把手搭建:Python + Shell监控脚本
1 准备一台监控服务器(或任何Linux机器)
- 阿里云、腾讯云、华为云均可,最低配置1核1G足够了
- 或者用你的本地电脑(但不建议关机)
2 核心监控脚本(Python版)
文件名:monitor.py
#!/usr/bin/env python3
import smtplib
from email.mime.text import MIMEText
import subprocess
import time
import sys
# ====== 配置区 ======
SERVERS = [
"192.168.1.1", # 替换为你的服务器IP或域名
"example.com",
"api.example.cn"
]
CHECK_INTERVAL = 180 # 秒,建议3分钟
# 邮箱配置
EMAIL_HOST = "smtp.qq.com"
EMAIL_PORT = 587
FROM_EMAIL = "your@qq.com"
FROM_PASSWORD = "你的邮箱授权码" # 注意:不是登录密码!
TO_EMAIL = "admin@example.com"
# ====================
def send_alert(machine, status):
msg = MIMEText(f"⚠️ 服务器宕机报警\n\n机器: {machine}\n状态: {status}\n时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
msg["Subject"] = f"服务器宕机通知 - {machine}"
msg["From"] = FROM_EMAIL
msg["To"] = TO_EMAIL
with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server:
server.starttls()
server.login(FROM_EMAIL, FROM_PASSWORD)
server.send_message(msg)
def check_machine(machine):
try:
# 先ping测试(快速检测网络是否可达)
result = subprocess.run(
["ping", "-c", "2", "-W", "5", machine],
capture_output=True,
timeout=10
)
if result.returncode == 0:
return "在线"
# ping失败后尝试TCP端口检测(避免防火墙屏蔽ICMP)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
# 这里可以改端口,例如检查Web服务器的80端口
sock.connect((machine, 80))
sock.close()
return "在线"
except Exception as e:
return f"离线({str(e)})"
def main():
last_status = {}
while True:
for sv in SERVERS:
current = check_machine(sv)
if current != "在线":
if last_status.get(sv) != "离线":
send_alert(sv, current)
print(f"[{time.strftime('%H:%M:%S')}] 发送报警: {sv} - {current}")
last_status[sv] = "离线"
else:
last_status[sv] = "在线"
time.sleep(CHECK_INTERVAL)
if __name__ == "__main__":
main()
3 Shell版精简监控(适合老手)
如果你不喜欢Python,下面是一个纯Shell版本:
#!/bin/bash
SERVERS="192.168.1.1 example.com api.example.cn"
EMAIL="admin@example.com"
INTERVAL=180
while true; do
for sv in $SERVERS; do
if ping -c 2 -W 5 $sv &>/dev/null; then
echo "$sv online" >> /dev/null
else
echo "服务器 $sv 宕机!" | mail -s "宕机警告" $EMAIL
fi
done
sleep $INTERVAL
done
4 部署运行
# 赋予执行权限 chmod +x monitor.py # 后台运行(nohup防止SSH退出结束) nohup python3 monitor.py > monitor.log 2>&1 & # 查看日志 tail -f monitor.log
邮件报警配置详解
1 获取邮箱授权码(以QQ邮箱为例)
- 登录QQ邮箱 → 设置 → 账户
- 找到“POP3/IMAP/SMTP服务”,点击“开启”
- 生成授权码(一串16位字母),注意:不是你的QQ密码!
- 将授权码填入脚本中的
FROM_PASSWORD字段
2 163邮箱/阿里云企业邮箱
- 163/126:同样需要开启SMTP并获取授权码
- 企业邮箱:一般使用
smtp.yourcompany.com端口587或465 - Gmail:需要开启“允许不够安全的应用”,然后使用应用专用密码
3 如何测试邮箱是否配置正确?
在脚本所在目录执行:
python3 -c "from email_monitor import send_alert; send_alert('test', '这是测试邮件')"
如果收到邮件,说明配置成功。
进阶优化:企业级监控方案
1 多服务器告警收敛
当5台服务器同时宕机(例如机房断电),你会收到5封邮件,这可能会淹没你的收件箱,优化方案:
# 在send_alert前增加“静默期”
SILENCE_TIME = 300 # 5分钟内相同IP不重复报警
if last_alert_time.get(machine, 0) + SILENCE_TIME < time.time():
send_alert(machine, current)
last_alert_time[machine] = time.time()
2 增加HTTP状态检查(不只是ping)
很多反代服务器会返回正常IP,但是web服务已经500,增加HTTP探测:
import requests
try:
r = requests.get(f"http://{machine}/health", timeout=5)
if r.status_code != 200:
send_alert(machine, f"HTTP状态码异常:{r.status_code}")
except:
send_alert(machine, "HTTP连接失败")
3 支持钉钉/企业微信/飞书报警
推荐方案:将邮件先发送到QQ邮箱,然后通过QQ邮箱的“来信自动转发”或“微信提醒”功能,或者直接修改脚本发送webhook:
import requests
requests.post("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key",
json={"msgtype":"text","text":{"content":"服务器宕机通知!"}})
常见问题与优化技巧
1 避免误报:多次检测机制
网络抖动可能导致一次ping失败就误报,改进方案:
# 连续失败3次才报警
fail_count = 0
for _ in range(3):
if check_machine(machine) != "在线":
fail_count += 1
time.sleep(30)
else:
break
if fail_count >= 3:
send_alert(machine, "连续3次检测失败")
2 支持国内网络环境
- CDN问题:有些域名被解析到国外CDN节点,国内服务器ping会丢包,建议用
curl检查实际业务端口。 - IPv6问题:如果服务器支持双栈,建议优先使用IPv4,在机器名的末尾加
-4。 - DNS缓存:建议在脚本中直接使用IP,或者每轮检测前清除DNS缓存。
3 脚本重启后自动恢复
使用systemd管理脚本(推荐):
# 创建服务文件 /etc/systemd/system/monitor.service [Unit] Description=Server Monitor After=network.target [Service] ExecStart=/usr/bin/python3 /root/monitor.py Restart=always RestartSec=30 User=root [Install] WantedBy=multi-user.target # 启用并启动 systemctl enable monitor systemctl start monitor # 查看状态 systemctl status monitor
4 如何监控云监控服务本身?
- Kubernetes集群:配合kube-state-metrics,监控Pod健康
- 数据库:MySQL可以用
mysqladmin ping检测 - 磁盘空间:增加磁盘使用率监控,超过90%自动报警
5 日志管理
建议按照日期切割日志:
# 启动时指定日志文件 nohup python3 monitor.py >> "/var/log/monitor_$(date +%Y%m%d).log" 2>&1 &
每月清理一次:
find /var/log -name "monitor_*.log" -mtime +30 -delete
总结与下一步行动
现在你拥有了一个免费、轻量、可定制的服务器宕机监控系统,但真正的价值不在于代码本身,而在于从“被动救火”到“主动预警”的转变,建议你立即行动:
- 花5分钟 将脚本部署到一台服务器
- 配置邮箱 并发送一次测试报警
- 设置通知 到手机微信(通过QQ邮箱提醒)
- 定期检查 脚本运行状态,确保它一直在跑
如果你用的是Windows服务器,也可以使用PowerShell版脚本(但需要配合计划任务),对于更复杂的监控需求(如多地区分布式监控、WebSocket实时通知),可以在此基础上扩展,但本文提供的方案已经覆盖了90%的日常场景。
最后提醒:监控脚本本身也要被监控。 建议每周手动检查一次日志,或者使用免费第三方监控(如StatusPage.io)作为外部保底。
请立即动手,让服务器宕机不再是噩梦。