用 curl + jq 给接口做一次靠谱的健康检查

举报
yd_274356910 发表于 2026/10/30 09:36:17 2026/10/30
【摘要】 只看进程和端口不够,本文讲存活与就绪端点怎么分、curl 如何设超时并用 jq 取关键字段,以及一个可直接复用的定时检查脚本和半夜排查顺序。

前几天半夜被报警吵醒,服务其实还活着,只是某个下游接口超时,整个页面跟着变慢。那次之后,我给常驻服务加了一套固定的健康检查做法:先分清接口是不是真的健康,再用脚本定期去探,最后把结果记下来,方便半夜排查时一眼看清问题在哪一环。

先说一个容易踩的坑:只看进程在不在,或者只看端口通不通,并不能说明服务可用。进程活着、端口监听着,但数据库连不上、缓存挂了、关键依赖超时,接口照样返回错误。所以健康检查要查到业务能真正跑通的那一层,至少要区分存活和就绪。

我常用的做法是给服务留两个端点。一个是存活端点,例如 GET /health,只回答进程本身是否还在工作,返回越轻越好,不查数据库、不做重计算。另一个是就绪端点,例如 GET /ready,在里面顺带检查数据库、缓存等关键依赖,依赖不通就明确返回不就绪,负载均衡就不会再把新流量分给它。两个端点分开,重启和摘流量就不会互相干扰。

有了端点,接下来就是用 curl 去探。最简单的检查只看状态码,不看正文:

curl -s -o /dev/null -w "%{http_code}" --max-time 3 http://127.0.0.1:8080/health
echo

这里有几个细节值得注意。-s 是安静模式,不输出进度;-o /dev/null 是丢掉正文,只关心状态;-w 输出状态码;–max-time 3 是给检查定一个上限,超过 3 秒没响应就按失败处理。没有超时限制的检查最危险,检查脚本自己先被拖住,后面一串检查全都会排队。

状态码能说明通不通,但说不清是哪一部分出了问题。这时候就该看正文,再用 jq 把字段取出来:

curl -s --max-time 3 http://127.0.0.1:8080/health | jq '{status: .status, db: .components.db.status, redis: .components.redis.status}'

如果返回里有 status、db、redis 这类字段,jq 一行就能把关键信息抽出来。比起把一整段 JSON 打印到日志里,这种方式在报警信息里也更干净。检查脚本里我一般还会把状态码和解析结果分开处理:先判断 HTTP 状态码是不是 200,再判断 jq 取到的 status 是不是 UP,两个都通过才算健康。

把一次检查写成脚本后,就可以交给定时任务定期跑。下面是一个可以直接改地址复用的小脚本思路:

#!/bin/bash
set -u
URL="http://127.0.0.1:8080/health"
CODE=$(curl -s -o /tmp/health.json -w "%{http_code}" --max-time 3 "$URL")
if [ "$CODE" != "200" ]; then
  echo "$(date '+%F %T') health check failed, http_code=$CODE" >> /var/log/health-check.log
  exit 1
fi
STATUS=$(jq -r '.status // empty' /tmp/health.json)
if [ "$STATUS" != "UP" ]; then
  echo "$(date '+%F %T') health check failed, status=$STATUS" >> /var/log/health-check.log
  exit 1
fi
echo "$(date '+%F %T') ok" >> /var/log/health-check.log

这个脚本只做三件事:取状态码、取状态字段、把结果写进日志。失败时日志里有时间和失败原因,成功时也留一条记录,方便事后对照报警时间。生产上不要把检查脚本写得太复杂,检查本身越重,越容易成为新的故障点。

最后说一下排查时的顺序,我现在基本固定下来:先看健康检查最近几次的结果,确认是偶发超时还是持续失败;再看 /ready 返回的依赖状态,定位到数据库还是缓存;最后才去翻应用日志。这样做的好处是,先用一个很轻的检查把范围缩小,再去翻重的日志,而不是一上来就在海量日志里大海捞针。

总结一下,靠谱的健康检查并不复杂:存活和就绪分开、检查一定要设超时、状态码和正文字段都要看、结果落到日志里。把这四点固定下来,下次半夜收到报警,至少能先知道服务是真挂了,还是某个依赖拖住了它。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。