0

curl批量检测网站状态码并自动告警脚本:5个实战方案让网站故障秒级感知

2026.06.14 | youres | 12次围观

前言

运维人员最怕什么?网站挂了自己还不知道。客户投诉了才发现,搜索引擎收录掉了才注意到——这种被动运维的痛,干过的都懂。

用 curl 批量检测网站状态码,再加上自动告警机制,就能把"事后救火"变成"事前预防"。本文分享5个从基础到进阶的实战方案,直接拿去用。

方案一:基础版——单次批量检测状态码

最核心的一条命令就搞定状态码采集:

curl -o /dev/null -s -w "%{http_code}" -m 5 https://example.com

参数解释:

  • -o /dev/null:丢弃响应体,只关心状态码
  • -s:静默模式,不显示进度条
  • -w "%{http_code}":只输出HTTP状态码
  • -m 5:5秒超时,防止卡死

扩展成批量检测脚本:

#!/bin/bash
# url_list.txt 每行一个URL
while read -r url; do
  code=$(curl -o /dev/null -s -w "%{http_code}" -m 5 "$url")
  echo "$url -> $code"
done < url_list.txt

这种方式简单直接,适合手动巡检或者配合 cron 定期执行。缺点是没有告警,出了问题还得人去看日志。

方案二:带重试机制——避免误报

网络抖动导致一次检测失败就告警?太草率了。加个重试机制靠谱得多:

#!/bin/bash
URL_LIST="https://api1.example.com https://api2.example.com https://api3.example.com"
MAX_RETRY=3
TIMEOUT=5

check_url() {
  local url=$1
  local fail=0
  for ((i=1; i<=MAX_RETRY; i++)); do
    code=$(curl -o /dev/null -s -w "%{http_code}" -m $TIMEOUT "$url")
    if [ "$code" -eq 200 ]; then
      echo "$url [OK] 状态码: $code (第${i}次)"
      return 0
    fi
    fail=$((fail+1))
    echo "$url [RETRY $i/$MAX_RETRY] 状态码: $code"
    sleep 2
  done
  echo "$url [FAIL] 连续${MAX_RETRY}次异常,状态码: $code"
  # 触发告警
  alert "$url" "$code"
  return 1
}

for url in $URL_LIST; do
  check_url "$url"
done

核心逻辑:连续3次检测都异常才触发告警。中间只要有一次返回200,就判定正常。这个阈值可以根据业务需求调整,对可用性要求高的服务可以把重试次数降到2次。

方案三:多指标检测——不只看状态码

光看状态码不够,还得看响应速度。一个200但响应要10秒的接口,用户体验也炸了。curl -w 可以同时采集多个指标:

#!/bin/bash
SLOW_THRESHOLD=3  # 慢请求阈值(秒)
URL_FILE="url_list.txt"
TIMEOUT=10

while read -r url; do
  # 一次性采集状态码和各项时间
  result=$(curl -o /dev/null -s -w "%{http_code}|%{time_connect}|%{time_starttransfer}|%{time_total}" -m $TIMEOUT "$url")
  code=$(echo "$result" | cut -d'|' -f1)
  connect=$(echo "$result" | cut -d'|' -f2)
  ttfb=$(echo "$result" | cut -d'|' -f3)
  total=$(echo "$result" | cut -d'|' -f4)
  
  echo "$url | 状态码: $code | 连接: ${connect}s | TTFB: ${ttfb}s | 总耗时: ${total}s"
  
  # 状态码异常告警
  if [ "$code" -ne 200 ] && [ "$code" -ne 301 ] && [ "$code" -ne 302 ]; then
    echo "[告警] $url 状态码异常: $code"
    alert "$url" "状态码异常: $code"
  fi
  
  # 响应超时告警
  if (( $(echo "$total > $SLOW_THRESHOLD" | bc -l) )); then
    echo "[告警] $url 响应过慢: ${total}s"
    alert "$url" "响应超时: ${total}s"
  fi
done < "$URL_FILE"

采集指标说明:

  • time_connect:TCP连接耗时
  • time_starttransfer:首字节时间(TTFB)
  • time_total:总响应时间

这种方式能同时发现宕机和性能退化两类问题,告警准确率更高。

方案四:Webhook告警通知

检测到异常怎么通知人?邮件太慢,Webhook秒级到达。以钉钉机器人为例:

alert() {
  local url=$1
  local msg=$2
  local webhook="https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
  local timestamp=$(date +%s%3N)
  
  # 生成签名(加签模式)
  sign=$(echo -n "${timestamp}\nSEC_KEY" | openssl dgst -sha256 -hmac "SEC_KEY" -binary | base64)
  encoded_sign=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$sign'))")
  
  local body="{\"msgtype\":\"text\",\"text\":{\"content\":\"[网站监控告警]\\nURL: $url\\n问题: $msg\\n时间: $(date '+%Y-%m-%d %H:%M:%S')\"}}"
  
  curl -s -X POST "$webhook&timestamp=$timestamp&sign=$encoded_sign" \
    -H 'Content-Type: application/json' \
    -d "$body" > /dev/null
}

支持的通知渠道可以根据团队习惯选择:

  • 钉钉机器人 Webhook(国内团队首选)
  • 企业微信 Webhook(配合加签验证)
  • 飞书 Webhook(支持富文本卡片)
  • Slack Webhook(海外团队常用)
  • Telegram Bot(个人运维最方便)

把 alert 函数集成到前面的检测脚本中,检测到异常就自动推送。整个流程完全自动化,不需要人盯着。

方案五:cron定时巡检+日志轮转

脚本写好了,配上 cron 就是完整的自动化巡检系统:

# 每5分钟巡检一次
*/5 * * * * /opt/scripts/site_monitor.sh >> /var/log/site_monitor.log 2>&1

# 日志轮转配置 /etc/logrotate.d/site_monitor
/var/log/site_monitor.log {
  daily
  rotate 30
  compress
  missingok
  notifempty
  create 0644 root root
}

日志轮转别漏了,不然磁盘被日志撑爆就是新故障。建议保留30天的历史日志,出了问题可以回溯排查。

crontab 配置注意事项:

  • 脚本路径用绝对路径,cron 环境变量和交互式 shell 不同
  • curl 命令也建议用绝对路径:/usr/bin/curl
  • 脚本开头加上 PATH=/usr/local/bin:/usr/bin:/bin
  • 检测频次建议5分钟,太频繁浪费资源,太间隔发现问题太晚

状态码判断技巧

不是所有非200都需要告警。合理的状态码分类:

  • 正常范围:200、301、302(301/302是合法重定向)
  • 需要告警:500、502、503(服务端故障)、0(连接超时或DNS解析失败)
  • 看情况:404(如果是API接口就要告警,如果是静态资源可以忽略)、403(权限问题可能正常)
  • 忽略:304(Not Modified,正常的缓存命中)

根据业务类型调整判断逻辑,避免无效告警导致告警疲劳。

总结

5个方案从简单到完善,覆盖了批量检测、重试容错、多维指标、自动告警、定时巡检的完整链路。建议根据实际场景组合使用:小站用方案二+方案四就够了,大团队用方案三+方案四+方案五搭建完整的监控体系。

脚本不复杂,但能解决实际问题。关键是"写完配上cron就别管了"——真正的自动化运维就是让自己"没事干"。

相关文章

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论