为什么需要监控网站状态码
网站突然打不开,用户投诉了才知道——这是很多站长的痛点。HTTP状态码是最直观的网站健康指标:200表示正常,301/302表示跳转,403是权限问题,500是服务器错误,000是连接失败。
用curl监控状态码,配合飞书告警,可以在用户发现之前就把问题揪出来。整个方案零成本,不需要任何第三方监控服务,一个Shell脚本就能搞定。
飞书自定义机器人Webhook配置步骤
在写监控脚本之前,先把飞书机器人配好。步骤很简单:
- 打开飞书,创建一个用于接收告警的群(建议专门建一个"网站监控告警"群)
- 点击群设置 → 群机器人 → 添加机器人
- 选择"自定义机器人",设置名称和描述
- 复制Webhook地址,格式类似:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx - 安全设置建议勾选"自定义关键词",填入
告警(后续脚本消息里必须包含这个词才会发送成功) - 点击完成,机器人就添加好了
注意:Webhook地址相当于密码,不要泄露到公开仓库或博客中。
脚本一:基础版curl监控加飞书告警
第一个脚本适合监控单个网站,逻辑清晰,容易理解:
#!/bin/bash
# 基础版:监控单个网站状态码,异常时推送飞书告警
WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/你的webhook地址"
URL="https://www.youres.cn"
KEYWORD="告警"
# 用curl获取HTTP状态码
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 10 "$URL")
if [ "$STATUS" != "200" ]; then
MSG="${KEYWORD}:网站异常!
网站地址:${URL}
HTTP状态码:${STATUS}
检测时间:$(date '+%Y-%m-%d %H:%M:%S')"
curl -s -X POST "$WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"msg_type\": \"text\",
\"content\": {
\"text\": \"${MSG}\"
}
}"
fi
这个脚本的核心是用 curl -s -o /dev/null -w "%{http_code}" 只拿状态码,不下载页面内容,速度快、开销小。
脚本二:批量检测多网站加飞书告警
实际运维中往往要监控多个网站,把URL写进数组,循环检测即可:
#!/bin/bash
# 批量版:同时监控多个网站,异常时逐条推送飞书告警
WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/你的webhook地址"
KEYWORD="告警"
# 要监控的网站列表
URLS=(
"https://www.youres.cn"
"https://blog.youres.cn"
"https://api.youres.cn"
)
TIMEOUT=10
DATE=$(date '+%Y-%m-%d %H:%M:%S')
for URL in "${URLS[@]}"; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT "$URL")
if [ "$STATUS" != "200" ]; then
MSG="${KEYWORD}:网站异常!
网站:${URL}
状态码:${STATUS}
检测时间:${DATE}"
curl -s -X POST "$WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"${MSG}\"}}"
sleep 1
fi
done
多网站监控的关键点是加 sleep 1,飞书Webhook有频率限制,发送太快会被拦截。
脚本三:带重试机制和详细告警信息
生产环境需要考虑网络抖动导致的误报,加一次重试可以过滤掉大部分假告警:
#!/bin/bash
# 生产版:带重试机制 + 响应时间 + 多网站批量检测
WEBHOOK="https://open.feishu.cn/open-apis/bot/v2/hook/你的webhook地址"
KEYWORD="告警"
TIMEOUT=10
URLS=(
"https://www.youres.cn"
"https://blog.youres.cn"
)
send_feishu() {
local msg="$1"
curl -s -X POST "$WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"${KEYWORD}:${msg}\"}}" > /dev/null 2>&1
}
check_url() {
local url="$1"
local result=$(curl -s -o /dev/null \
-w "%{http_code}|%{time_total}" \
--connect-timeout $TIMEOUT \
--max-time $TIMEOUT \
"$url")
echo "$result"
}
for URL in "${URLS[@]}"; do
result1=$(check_url "$URL")
STATUS1=$(echo "$result1" | cut -d'|' -f1)
TIME1=$(echo "$result1" | cut -d'|' -f2)
if [ "$STATUS1" != "200" ]; then
sleep 5
result2=$(check_url "$URL")
STATUS2=$(echo "$result2" | cut -d'|' -f1)
TIME2=$(echo "$result2" | cut -d'|' -f2)
if [ "$STATUS2" != "200" ]; then
MSG="网站持续异常!
地址:${URL}
第一次检测:状态码=${STATUS1}
第二次检测:状态码=${STATUS2},耗时=${TIME2}s
请及时处理!"
send_feishu "$MSG"
sleep 1
fi
fi
done
这个版本还加了 time_total 响应时间,网站虽然返回200但响应超过5秒,也值得关注。
crontab定时任务配置
脚本写好了,配置crontab让它自动跑:
# 每5分钟检测一次
*/5 * * * * /path/to/your/monitor_script.sh >> /var/log/website_monitor.log 2>&1
建议检测间隔设为3-5分钟,太频繁会对服务器产生不必要的请求压力,太久则故障发现不及时。
常见问题排查
飞书机器人收不到消息
检查三点:Webhook地址是否正确、消息里是否包含设置的关键词、是否触发了频率限制(同一机器人每分钟最多20条)。
curl获取的状态码是000
000表示curl根本没拿到HTTP响应,通常是DNS解析失败、连接超时、或者网站IP被封。可以先用 curl -v 看详细连接过程。
脚本在crontab里不执行
crontab的环境变量和登录Shell不同,curl路径要用绝对路径 /usr/bin/curl,或者在脚本开头加 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。
相关文章
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论