用 Shell 脚本监控网站存活状态(附源码)
大家好,我是33blog的技术博主。今天想分享一个我在实际运维工作中经常用到的实用技巧——用Shell脚本监控网站存活状态。这个方案特别适合中小型项目,不需要依赖复杂的监控系统,几行代码就能搞定基础监控需求。
为什么选择Shell脚本?
记得我刚入行时,公司预算有限买不起商业监控系统。当时用Python写了个监控脚本,结果服务器上连Python环境都没装全…后来发现其实Shell才是Linux系统的”母语”,几乎不需要任何额外依赖。
Shell脚本的优势很明显:
- 轻量级,几乎不占系统资源
- 无需额外安装环境
- 可以轻松集成到crontab定时任务
- 调试方便,直接命令行就能测试
基础监控脚本实现
先来看一个最简单的实现版本,这个脚本会检查网站是否返回200状态码:
#!/bin/bash
URL="https://example.com"
STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}" $URL)
if [ $STATUS_CODE -ne 200 ]; then
echo "网站异常!状态码: $STATUS_CODE" | mail -s "网站监控警报" admin@example.com
fi
这个脚本虽然只有几行,但已经实现了核心功能。不过实际使用中我发现几个问题:
- 没有超时控制,如果网站完全挂掉会卡住
- 没有重试机制,偶发故障可能误报
- 报警方式单一,只有邮件
进阶版监控脚本
基于实际运维经验,我优化了一个更健壮的版本:
#!/bin/bash
# 配置部分
URLS=("https://example.com" "https://api.example.com")
MAX_RETRY=3
TIMEOUT=10
ALERT_EMAIL="admin@example.com"
LOG_FILE="/var/log/website_monitor.log"
# 监控函数
check_website() {
local url=$1
local retry=0
while [ $retry -lt $MAX_RETRY ]; do
STATUS_CODE=$(curl -o /dev/null -s -w "%{http_code}" --max-time $TIMEOUT $url)
if [ $STATUS_CODE -eq 200 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - $url 检测正常" >> $LOG_FILE
return 0
fi
((retry++))
sleep 1
done
# 所有重试都失败
echo "$(date '+%Y-%m-%d %H:%M:%S') - $url 检测失败,最终状态码: $STATUS_CODE" >> $LOG_FILE
echo "$url 服务异常!状态码: $STATUS_CODE (重试 $MAX_RETRY 次)" |
mail -s "紧急:$url 服务异常" $ALERT_EMAIL
return 1
}
# 主程序
for url in "${URLS[@]}"; do
check_website $url
done
实际使用中的优化点
在线上环境跑了半年后,我又做了几个实用优化:
1. 添加Telegram报警
邮件报警有时候不够及时,我加上了Telegram机器人通知:
send_telegram() {
local message=$1
local bot_token="YOUR_BOT_TOKEN"
local chat_id="YOUR_CHAT_ID"
curl -s -X POST "https://api.telegram.org/bot$bot_token/sendMessage"
-d "chat_id=$chat_id&text=$message" > /dev/null
}
2. 响应时间监控
有时候网站虽然能访问但响应很慢,于是增加了响应时间记录:
RESPONSE_TIME=$(curl -o /dev/null -s -w "%{time_total}" --max-time $TIMEOUT $url)
echo "响应时间: ${RESPONSE_TIME}s" >> $LOG_FILE
3. 自动重启服务
对于一些关键服务,配置了自动恢复机制(慎用!):
if [ $STATUS_CODE -ne 200 ]; then
systemctl restart nginx
# 记录重启操作
echo "$(date) - 自动重启nginx服务" >> /var/log/auto_recovery.log
fi
部署建议
建议把脚本放到/usr/local/bin/
下,然后通过crontab定时执行:
# 每5分钟检查一次
*/5 * * * * /usr/local/bin/website_monitor.sh
记得给脚本执行权限:
chmod +x /usr/local/bin/website_monitor.sh
踩坑记录
最后分享几个我踩过的坑:
- 权限问题:crontab执行环境与终端不同,路径和权限要特别注意
- 邮件发送失败:服务器需要配置好mailutils或sendmail
- 日志轮转:长期运行要配置logrotate,避免日志文件过大
- 误报警:对于偶发故障,适当增加重试次数
这个方案虽然简单,但在我的生产环境中稳定运行了2年多,成功捕获了数十次服务异常。希望对你有帮助!如果有更好的建议,欢迎在评论区交流~
这个脚本太实用了,正好解决了我手头的问题!
建议加上短信报警会更及时,我们公司之前就因为邮件延迟错过了一次故障处理
初学者问下,curl命令在哪些系统上都能用吗?🤔
博主考虑过用Python重写吗?感觉可读性会更好些
太专业了看不懂,但收藏备用!