在浏览器输入一个网址后,请求通常要经过 DNS、网络连接、TLS、CDN 或反向代理,最后才到应用。返回的 HTML 也不是终点,浏览器还要继续下载样式、脚本、字体和图片。MDN 对网页工作方式的说明(在新标签页打开)也把 DNS、HTTP 请求、服务器响应和浏览器组装页面列为连续环节。
浏览器先拆解网址
以 https://example.com/posts/guide/?from=search#step-2 为例:
https决定协议和默认端口;example.com是需要解析的主机名;/posts/guide/是服务器会收到的路径;from=search是查询参数,可能影响 CDN 缓存和应用逻辑;#step-2只用于浏览器内定位,不会随 HTTP 请求发送。
浏览器还会检查已有的 DNS 结果、连接、HTTP 缓存、Service Worker 和 HSTS。页面刷新一次,并不代表整条链路都会重新执行。
DNS 找到的是入口,不一定是源站
本机没有可用缓存时,系统解析器会向递归 DNS 查询。递归 DNS 也没有缓存,才会沿根域、顶级域和权威 DNS 找到记录。
网站可能直接返回 A 或 AAAA 地址,也可能通过 CNAME 指向 CDN。浏览器连接的是最终解析出的入口,通常看不到入口之后还有哪些源站和内部网络。
dig +short example.com NS
dig +short www.example.com CNAME
dig +short www.example.com A
dig +short www.example.com AAAA
本机代理或特殊 DNS 可能返回合成地址。结果看起来不对时,可以指定公共解析器,或者直接追踪权威链路:
dig @1.1.1.1 example.com A
dig +trace example.com
A、AAAA、CNAME、TXT 和 CAA 的具体区别,见 DNS 记录怎么选。
建立连接后,HTTPS 还要完成 TLS
HTTP/1.1 和 HTTP/2 通常使用 TCP;HTTP/3 使用基于 UDP 的 QUIC。拿到入口地址后,客户端先建立传输连接,再为 HTTPS 完成 TLS 握手。
浏览器会检查证书是否覆盖当前域名、是否过期、证书链是否可信,并与服务端协商加密参数和应用层协议。证书名称错误发生在请求到达应用之前,因此应用日志里往往没有对应记录。
curl -sS -o /dev/null \
-w 'http=%{http_version} code=%{http_code} remote=%{remote_ip}\n' \
https://example.com/
openssl s_client -connect example.com:443 \
-servername example.com </dev/null
CDN 和反向代理做的不是同一件事
CDN 更靠近访问者。缓存命中时,边缘节点可以直接返回文件;未命中时,才向源站取回内容。判断 CDN 是否工作,不能只看 CNAME,还要连续请求同一个 URL:
curl -sS -D - -o /dev/null https://cdn.example.com/path/image.webp
curl -sS -D - -o /dev/null https://cdn.example.com/path/image.webp
X-Cache、Age、ETag 和 Cache-Control 可以帮助判断内容是否来自预期源站、能否缓存,以及第二次请求是否命中。
反向代理通常位于源站入口。它按照域名和路径,把请求转发到正确的应用端口,并处理 HTTPS、跳转、压缩、WebSocket 和访问日志。出现 502 时,最有用的检查不是宿主机上的 curl localhost,而是确认代理所在的网络能否访问上游。
应用返回 HTML 后,页面还没加载完
应用可能继续访问缓存、数据库、对象存储或第三方 API。HTML 返回浏览器后,浏览器还要构建 DOM、下载资源、计算布局、执行脚本并绘制页面。
首字节耗时和页面可用时间要分开判断:
- 首字节很慢:更可能卡在网络、CDN 回源、反向代理、应用或数据库;
- 首字节正常但页面迟迟不可用:更可能是资源体积、请求数量、JavaScript 主线程或渲染问题。
用 curl 拆开页面各阶段耗时
curl -sS -o /dev/null \
-w $'dns=%{time_namelookup}\nconnect=%{time_connect}\ntls=%{time_appconnect}\nttfb=%{time_starttransfer}\ntotal=%{time_total}\n' \
https://example.com/
这些字段是累计时间,需要用相邻时间相减,才能看到某一段实际花了多久。各变量的准确含义以 curl --write-out 文档(在新标签页打开)为准;连接复用、代理和 HTTP/3 会改变部分阶段是否出现以及怎样计时。
| 变慢的区间 | 近似计算 | 优先查看 |
|---|---|---|
| DNS | time_namelookup | 解析器、权威 DNS、记录和 TTL |
| TCP 建连 | time_connect - time_namelookup | 路由、丢包、入口地域和端口 |
| TLS | time_appconnect - time_connect | 证书链、网络往返和会话复用 |
| 等待首字节 | time_starttransfer - time_appconnect | CDN 回源、代理、应用和数据库 |
| 下载正文 | time_total - time_starttransfer | 内容体积、带宽和压缩 |
按报错位置缩小范围
| 现象 | 先查哪里 |
|---|---|
| 找不到域名、解析失败 | NS、A/AAAA、CNAME 和本机 DNS |
| 连接被拒绝或超时 | 入口地址、端口、防火墙和安全组 |
| 证书名称或有效期错误 | DNS 指向、SNI 和入口证书 |
| 静态资源时新时旧 | CDN 缓存键、TTL、Age 和 ETag |
| 502 | 反向代理到上游的网络与端口 |
| 504 | 上游处理时间、代理超时和慢查询 |
| TTFB 正常但页面仍慢 | 浏览器 Network 和 Performance 面板 |
按 DNS、连接、证书、CDN、代理、应用和浏览器的顺序从外向内排查。证书尚未完成握手时,数据库日志与当前故障无关。
保留 DNS 最终应答、客户端分段耗时,以及入口与应用日志中的同一请求。浏览器报错页或单次 ping 无法定位故障层级。
常见问题
在浏览器输入网址后,最先发生什么?
浏览器先解析 URL,并检查本地 DNS、已有连接和 HTTP 缓存。需要重新解析时,才通过系统解析器查询域名对应的入口地址。
DNS 完成后会直接连接源站吗?
不一定。DNS 可能把域名指向 CDN、负载均衡器或反向代理。客户端连接的是最终解析出的入口,再由入口决定是否访问源站。
TLS 握手和 HTTPS 是一回事吗?
TLS 握手负责身份验证、算法协商和密钥建立;握手完成后,HTTP 才在加密连接中传输。HTTPS 指的是这一整套组合。
TTFB 高就一定是后端慢吗?
不一定。TTFB 包含 DNS、建连、TLS、CDN 回源、代理等待和应用处理。先拆开各段耗时,再对照入口与应用日志定位慢点。
怎样判断请求是否经过 CDN?
先检查 CNAME,再看真实 GET 响应中的 CDN 特征头、缓存状态、Age 和 ETag。CNAME 正确只能说明 DNS 已指向 CDN,不能证明当前文件已经命中缓存。