用 Shell 脚本监控网站存活状态(附源码)

2025.6.21 杂七杂八 1812
33BLOG智能摘要
文章介绍了一个用于监控网站存活状态的Shell脚本方案。作者基于自身运维经验,指出Shell脚本轻量、易集成、无需额外环境的优势,并提供了基础和进阶版脚本示例。进阶版本具有多地址检查、重试机制、超时控制和邮件报警功能。文章还提到实际部署中的优化点,如添加Telegram通知、记录响应时间和配置自动重启,以及在安装和使用中需要注意的问题,如权限、邮件配置和日志管理。该方案已在实际环境中稳定运行两年以上,能够有效检测服务异常。
— 此摘要由33BLOG基于AI分析文章内容生成,仅供参考。

用 Shell 脚本监控网站存活状态(附源码)

用 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
Bash

这个脚本虽然只有几行,但已经实现了核心功能。不过实际使用中我发现几个问题:

  1. 没有超时控制,如果网站完全挂掉会卡住
  2. 没有重试机制,偶发故障可能误报
  3. 报警方式单一,只有邮件

进阶版监控脚本

基于实际运维经验,我优化了一个更健壮的版本:

#!/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
Bash

实际使用中的优化点

在线上环境跑了半年后,我又做了几个实用优化:

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
}
Bash

2. 响应时间监控

有时候网站虽然能访问但响应很慢,于是增加了响应时间记录:

RESPONSE_TIME=$(curl -o /dev/null -s -w "%{time_total}" --max-time $TIMEOUT $url)
echo "响应时间: ${RESPONSE_TIME}s" >> $LOG_FILE
Bash

3. 自动重启服务

对于一些关键服务,配置了自动恢复机制(慎用!):

if [ $STATUS_CODE -ne 200 ]; then
    systemctl restart nginx
    # 记录重启操作
    echo "$(date) - 自动重启nginx服务" >> /var/log/auto_recovery.log
fi
Bash

部署建议

建议把脚本放到/usr/local/bin/下,然后通过crontab定时执行:

# 每5分钟检查一次
*/5 * * * * /usr/local/bin/website_monitor.sh
Bash

记得给脚本执行权限:

chmod +x /usr/local/bin/website_monitor.sh
Bash

踩坑记录

最后分享几个我踩过的坑:

  • 权限问题:crontab执行环境与终端不同,路径和权限要特别注意
  • 邮件发送失败:服务器需要配置好mailutils或sendmail
  • 日志轮转:长期运行要配置logrotate,避免日志文件过大
  • 误报警:对于偶发故障,适当增加重试次数

这个方案虽然简单,但在我的生产环境中稳定运行了2年多,成功捕获了数十次服务异常。希望对你有帮助!如果有更好的建议,欢迎在评论区交流~

评论

  • 这个脚本太实用了,正好解决了我手头的问题!

  • 建议加上短信报警会更及时,我们公司之前就因为邮件延迟错过了一次故障处理

  • 初学者问下,curl命令在哪些系统上都能用吗?🤔

  • 博主考虑过用Python重写吗?感觉可读性会更好些

  • 太专业了看不懂,但收藏备用!