HTTP 诊断
目标
从状态码、响应头、耗时和正文四个维度解读 HTTP 响应,并将这些检查整合成健康检查脚本。
为什么重要
收到“响应很慢”的反馈时,需要的不是更多仪表盘,而是把一次请求的耗时拆分到各个阶段来观察。curl -w 的计时变量会分别告诉你名称解析 / TCP 连接 / TLS / 服务器首字节 / 正文传输所花的时间。如果到 time_connect 为止都正常,只有 time_starttransfer 很大,那么网络没有问题,应用程序才是原因——争论当场就能结束。此外,健康检查必须设置最长等待时间。否则对方不响应时,脚本会永远卡住;如果 cron 每 5 分钟启动一次,进程就会不断堆积。
步骤
使用 /root/www 作为文档根目录,使用 /root/http 作为工作目录。
- 创建
/root/www/index.html并写入labhub-http-ok,然后在后台启动python3 -m http.server 8000 --bind 127.0.0.1 --directory /root/www,将其 PID 写入/root/http/server_pid.txt。 - 请求一个不存在的路径,并将状态码仅以数字形式写入
/root/http/status404.txt。 - 只获取
/index.html的响应头并保存到/root/http/headers.txt。不得混入正文。 - 将请求的
time_namelookup、time_connect、time_total三个值用空格分隔,保存为/root/http/timing.txt中的一行。 - 创建
/root/www/api.json。name必须为labhub,tags必须是至少包含两个值的数组。然后从服务器获取该文件,将tags的第二个值写入/root/http/tag.txt。 - 创建
/root/www/sub目录并在其中放入一个文件。分别在不跟随重定向和跟随重定向的情况下请求http://127.0.0.1:8000/sub,将状态码按以下两行写入/root/http/redirect.txt。no_follow=<코드>follow=<코드>
- 发送 POST 请求,并将状态码写入
/root/http/method.txt,格式为post=<코드>。 - 创建
/root/http/healthcheck.sh <URL>。- 如果是 2xx,输出
ok code=<코드> time=<초>,并以退出码0结束 - 如果收到了响应但不是 2xx,输出
down code=<코드>,并以退出码1结束 - 如果根本无法连接,输出以
down开头的消息,并以退出码1结束。必须在 10 秒内完成判定。
- 如果是 2xx,输出
参考
- 使用
curl -s -o /dev/null -w '%{http_code}' URL只提取状态码。连接失败时会得到000。 curl -sI URL使用 HEAD 请求,只获取响应头。- 使用
curl --max-time 5设置最长等待时间。 - 常见错误 1:如果在第 6 步不使用
-L也得到 200,说明请求时在路径末尾加了斜杠。必须不带斜杠请求,才会得到 301。 - 常见错误 2:如果在第 8 步只把
000当作数字比较,就无法区分连接失败和正常响应。
启动本地 HTTP 服务器
创建 /root/www/index.html 并写入 labhub-http-ok,然后在后台启动 python3 -m http.server 8000 --bind 127.0.0.1 --directory /root/www,将其 PID 写入 /root/http/server_pid.txt。
python3 -m http.server 提供了指定文档根目录的选项。请仅绑定到 127.0.0.1。
只提取状态码
请求一个不存在的路径,并将状态码仅以数字形式写入 /root/http/status404.txt。
有一个 -w 变量可以丢弃正文,只输出状态码。
只获取响应头
只获取 /index.html 的响应头并保存到 /root/http/headers.txt。不得混入正文。
使用发送 HEAD 请求的选项。文件中不得混入正文。
测量各阶段耗时
将请求的 time_namelookup、time_connect、time_total 三个值用空格分隔,保存为 /root/http/timing.txt 中的一行。
使用 -w,将 time_namelookup、time_connect、time_total 三个值以空格分隔并输出为一行。
从 JSON 响应中提取值
创建 /root/www/api.json。name 必须为 labhub,tags 必须是至少包含两个值的数组。然后从服务器获取该文件,将 tags 的第二个值写入 /root/http/tag.txt。
将 curl 的输出传给 jq。数组索引从 0 开始。
跟随重定向
创建 /root/www/sub 目录并在其中放入一个文件。分别在不跟随重定向和跟随重定向的情况下请求 http://127.0.0.1:8000/sub,将状态码按以下两行写入 /root/http/redirect.txt。
no_follow=<코드>follow=<코드>
curl 默认不跟随重定向。如果目录路径末尾没有斜杠,服务器会返回 301。
未实现方法的响应
发送 POST 请求,并将状态码写入 /root/http/method.txt,格式为 post=<코드>。
使用 -X 指定方法。此服务器只实现了 GET 和 HEAD。
健康检查脚本
创建 /root/http/healthcheck.sh <URL>。
- 如果是 2xx,输出
ok code=<코드> time=<초>,并以退出码0结束 - 如果收到了响应但不是 2xx,输出
down code=<코드>,并以退出码1结束 - 如果根本无法连接,输出以
down开头的消息,并以退出码1结束。必须在 10 秒内完成判定。
需要区分正常、非 2xx 和无法连接三种情况。务必设置最长等待时间。