curl 与 shell 轻量接口巡检
【摘要】 Prometheus 加 blackbox_exporter、云监控的可用性探测,都比手写脚本完善。但很多团队的真实需求只是“十几个接口、每五分钟看一次、挂了在群里说一声”。为这点事搭一套采集、存储和
一、先明确要解决的问题
Prometheus 加 blackbox_exporter、云监控的可用性探测,都比手写脚本完善。但很多团队的真实需求只是“十几个接口、每五分钟看一次、挂了在群里说一声”。为这点事搭一套采集、存储和面板,成本远高于收益。
自研脚本真正要解决的有三件事:能不能反复执行而结果一致(幂等)、失败信息能不能留档对比、告警能不能不刷屏。这三件事和“能不能探通”无关,却决定了这套东西能不能长期跑下去。
二、先手动验证一个接口
别急着写循环,先用一条命令确认输出格式符合预期:
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' \
--max-time 5 --retry 2 --retry-delay 1 \
https://www.huaweicloud.com/
几个容易踩的点:
-sS:静默进度条但保留错误信息,出错时能看到原因。-o /dev/null:丢掉 body,巡检只看状态码和耗时。--max-time必须给,否则 DNS 解析或 TLS 握手卡住时,整个脚本会被一个接口拖死。- 接口返回 404/500 时,curl 的退出码仍是 0。判断成败只能看
%{http_code};只有连不上、超时这类情况退出码才非 0,此时要兜底成000。
三、把循环写成幂等的
幂等在这里的具体含义是:跑一次和跑十次,系统状态和输出完全一样。对应三条约束:
- 不要用
set -e。第一个接口超时就退出,后面的接口根本没被巡检,这次结果不可重复。用set -uo pipefail即可。 - 结果文件覆盖写,不追加。每次产出同一份
last.tsv,随时可以diff出变化。 - 告警只和上一次状态比,状态翻转才发。这样连续失败不会每五分钟刷一遍群。
脚本对被测系统只读,唯一的副作用是本地状态文件,且用 mv 原子替换,中途被打断也不会留下半份状态。
#!/usr/bin/env bash
set -uo pipefail
TARGETS=(
"home|https://www.huaweicloud.com/|200"
"api|https://bss.myhuaweicloud.com/v1/health|200"
)
STATE=/var/lib/probe/state.tsv
OUT=/var/log/probe/last.tsv
mkdir -p "$(dirname "$STATE")" "$(dirname "$OUT")"
touch "$STATE"
tmp=$(mktemp)
for t in "${TARGETS[@]}"; do
IFS='|' read -r name url want <<<"$t"
out=$(curl -sS -o /dev/null -w '%{http_code} %{time_total}' \
--max-time 5 --retry 2 --retry-delay 1 "$url" 2>/dev/null) || out="000 0"
read -r code cost <<<"$out"
ok=FAIL; [ "$code" = "$want" ] && ok=OK
printf '%s\t%s\t%s\t%s\n' "$name" "$ok" "$code" "$cost" >>"$tmp"
done
# 只在状态翻转时输出一行,其余静默
while IFS=$'\t' read -r name ok code cost; do
prev=$(awk -F'\t' -v n="$name" '$1==n{print $2}' "$STATE")
[ -n "$prev" ] && [ "$ok" != "$prev" ] && \
echo "[$(date -Is)] $name $prev -> $ok (http=$code t=${cost}s)"
done <"$tmp"
mv "$tmp" "$OUT"
awk -F'\t' '{print $1"\t"$2}' "$OUT" >"$STATE"
四、挂到 crontab 并验证幂等
*/5 * * * * /usr/local/bin/probe.sh >> /var/log/probe/alerts.log 2>&1
验证方法很直接:
- 连续执行两次,
diff两份last.tsv应当无输出。 - 用
iptables -A OUTPUT -d <ip> -j DROP模拟故障,日志里应只出现一次OK -> FAIL,之后不再刷。 - 恢复规则后,应只再出现一次
FAIL -> OK。
另外注意最坏耗时约为 (retry+1) × max-time,cron 周期要留够,否则进程会堆积。接口多时可以用 curl 7.66+ 的 --parallel 并发拉取。
五、小结
这套巡检的价值不在“能发请求”,而在“每次跑完都是同一份可对比的结果”。三条线守住了幂等:出错不中断、输出覆盖写、告警看翻转。代码只有几十行,随时可以改目标、改阈值,也能在出问题时用 bash -x 单步复现,这是重型监控方案换不来的可控性。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)