Shell脚本监控网站http状态码,异常告警
网站突然打不开,等用户反馈才发现?
其实用一段 Shell 脚本就能定时检测 HTTP 状态码,一旦返回非 200 就自动发告警。
本文从零开始,带你写出可直接运行的监控脚本,并配置成定时任务,最终实现异常自动通知。
准备条件
开始前,请确认服务器满足以下条件:
- Linux 系统(CentOS、Ubuntu、Debian 均可),已安装
curl和crontab。 - 一个可用的告警通道,例如邮件(需配置
mailx或sendmail)、钉钉机器人 Webhook、企业微信机器人 Webhook。本文以钉钉机器人 Webhook 为例,邮件方式会在避坑部分说明。 - 目标网站地址,例如
https://www.example.com。
检查命令:
which curl crontab
curl --version
如果 curl 未安装,执行 yum install curl -y 或 apt install curl -y。
编写监控脚本
创建脚本文件 /opt/check_http.sh,内容如下:
#!/bin/bash
# 监控的网址列表,一行一个
URLS=(
"https://www.example.com"
"https://www.example.com/blog"
)
# 钉钉机器人 Webhook 地址
WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=你的token"
# 超时时间(秒)
TIMEOUT=10
# 临时记录异常信息
ALERT_MSG=""
for url in "${URLS[@]}"; do
# 获取 HTTP 状态码,-o /dev/null 丢弃正文,-s 静默,-w 输出状态码
code=$(curl -o /dev/null -s -w "%{http_code}" --connect-timeout $TIMEOUT "$url")
if [ "$code" -ne 200 ]; then
ALERT_MSG="${ALERT_MSG}异常网址: $url 状态码: $code\n"
fi
done
# 如果有异常,发送告警
if [ -n "$ALERT_MSG" ]; then
curl -s -H "Content-Type: application/json" \
-d "{\"msgtype\": \"text\", \"text\": {\"content\": \"网站监控告警\n$ALERT_MSG\"}}" \
"$WEBHOOK"
fi
保存后赋予执行权限:
chmod +x /opt/check_http.sh
关键点:curl -w "%{http_code}" 负责输出状态码,-o /dev/null 避免下载页面内容,--connect-timeout 防止长时间卡住。
配置定时任务
使用 crontab -e 编辑当前用户的定时任务,添加一行:
*/5 * * * * /bin/bash /opt/check_http.sh
这表示每 5 分钟执行一次监控。
保存后,可以通过 crontab -l 查看是否添加成功。
如果脚本中调用了 curl 或 mailx,建议在 crontab 中显式指定 PATH,例如:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/5 * * * * /bin/bash /opt/check_http.sh
避坑指南
- 状态码误判:有些网站会返回 301 或 302 跳转,如果只判断 200 就会误报。可以在 curl 中加入
-L跟随跳转,再判断最终状态码。 - 告警风暴:如果网站持续异常,每 5 分钟发一次告警会刷屏。建议在脚本中增加判断,例如记录上次状态,只有状态变化时才发送,或使用告警静默期。
- 邮件发送失败:若使用
mailx,需确保本机已配置 MTA(如 postfix)或外部 SMTP,否则邮件无法发出。可先手动执行echo test | mail -s test your@email.com验证。 - Webhook 安全:钉钉机器人 Webhook 包含 access_token,不要将脚本上传到公开仓库。
验证效果
手动执行一次脚本,观察是否有输出或告警:
/bin/bash /opt/check_http.sh
如果一切正常,没有异常网址时脚本不会发送任何消息。
可以临时将 URL 改为一个不存在的地址,例如 https://www.example.com/not-exist-123,再次执行,检查钉钉是否收到告警。
测试完成后记得改回真实网址。
此外,查看 crontab 日志确认任务是否按时执行:
grep CRON /var/log/syslog # Debian/Ubuntu
grep CRON /var/log/cron # CentOS/RHEL
常见疑问
脚本可以监控 HTTPS 证书过期吗?
可以,使用 curl -vI --stderr - 并解析输出中的证书有效期,但解析较复杂,建议使用专用工具如 ssl-cert-check。
能否同时监控多个网站并区分告警?
可以,在脚本中定义数组存放多个 URL,循环检测,告警信息中带上对应网址即可。
如果服务器无法访问外网,脚本还能用吗?
不能,需要确保服务器能正常访问被监控的网址,否则所有检测都会失败。
告警频率太高怎么办?
可以结合状态文件记录上一次检测结果,只在状态变化时发送告警,或者将检测间隔调整为 10 分钟以上。
按以上步骤操作后,你就拥有了一个轻量级的网站 HTTP 状态码监控方案。
如果遇到脚本不执行、告警收不到等问题,优先检查 crontab 环境变量和告警通道配置。