页面打不开时,第一反应往往是“网有问题”或“服务器挂了”。这两种判断差别很大:前者查链路,后者查服务。一条 curl 命令能同时给出两边的线索。

什么情况下用得上

浏览器里某个地址转圈很久或直接报错,但说不清卡在哪一环,又不想开抓包工具或开发者工具。此时只需确认三件事:对方有没有回话、回的是什么状态、花了多长时间。curl -I 只请求响应头,不下载正文,适合快速探测。

命令在做什么

curl -I -L -w '%{http_code} %{time_total}\n' -o /dev/null https://example.com/
  • -I 发 HEAD 请求,只要响应头。
  • -L 跟随重定向。不加它,遇到 301/302 就停在第一跳,看不到最终状态。
  • -w '%{http_code} %{time_total}' 在末尾追加最终状态码和总耗时(秒)。
  • -o /dev/null 丢弃响应头正文,终端只剩 -w 那一行。

输出先是若干行 HTTP/1.1 200 OK,最后一行是 200 0.842。

怎么读这两个数

状态码:2xx 服务正常应答;3xx 还在跳转,配合 -L 应落到 2xx;4xx 多半是路径、权限或参数问题,服务本身活着;5xx 是服务端出错;完全没有状态码、只有 curl: (…) 报错,说明 TCP 连接或 TLS 握手都没完成。

耗时:time_total 一秒以内通常正常。注意 -I 只取头,正文几乎为零,所以耗时基本反映建连、TLS 握手和首字节等待,不含下载时间。

状态码 耗时 判断
2xx 短 链路和服务都正常,问题可能在浏览器侧
2xx 长 服务能应答但慢,查后端处理或首字节延迟
5xx 任意 服务活着但内部出错,查服务日志
4xx 短 请求本身有问题,地址或鉴权不对
无 长或超时 网络层问题,DNS、路由或防火墙

分步确认

第一步,先跑一次不带 -L 的命令看第一跳。若第一跳是 301,说明有重定向,加 -L 再看最终落点。

第二步,把耗时拆开:

curl -I -L -o /dev/null -w 'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}\n' https://example.com/

哪一段明显偏大,问题就在哪一段。DNS 慢查解析配置,连接慢查路由和防火墙,TLS 慢查证书链,首字节慢多半是服务端在排队。

第三步,换一个已知正常的地址做对照。对照地址快、目标地址慢,问题在目标侧;两个都慢,问题在本机网络出口。

怎么判断哪一步失败

只有 curl: 开头的错误行、没有状态码,说明请求没走完。Could not resolve host 是 DNS 失败,Connection timed out 是 TCP 连不上,SSL certificate problem 是证书校验没过——都属于网络或配置层,不是服务逻辑故障。反过来,只要有状态码输出,连接就已建立、对方应用层回了话,剩下的是解读状态码。

边界与代价

-I 发的是 HEAD 请求,少数服务对 HEAD 的实现和 GET 不一致,可能返回 405 或与真实页面不同的状态码。要更贴近真实访问,把 -I 换成 GET 配合 -o /dev/null,代价是会实际传输正文。

单次耗时受瞬时波动影响,判断“慢”之前建议连跑两三次。-L 跟随重定向时,time_total 是整条跳转链的累计值,跳转多时会偏大,需结合每一跳的状态码分别看。

这条命令只测一个地址的一次请求,适合快速分诊,不能替代对整条链路的持续监控。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注