Appearance
第 1 讲|一次访问网站
浏览器输入一个网址回车,看似简单的一步,背后涉及至少五六层不同的技术机制。每一层都可能成为访问失败的原因。理解这一过程的核心目的不是为了"知道有多少步骤",而是为了当访问出现问题时,能够准确判断卡在哪一层——浏览器报 DNS_PROBE_FINISHED_NXDOMAIN 是 DNS 层的问题,显示 502 是入口层到后端的问题,页面打开但接口转圈是后端或数据库的问题。
本讲围绕一个简单的访问场景,把涉及的核心对象逐一拆开:URL 结构、DNS 解析、TCP/TLS 握手、HTTP 请求、入口层、后端、页面资源加载。每一层都给出对应的判定信号——出现什么现象就指向哪一层的问题。

一、URL 结构
浏览器地址栏里的完整地址,正式名称是 URL(Uniform Resource Locator)。一个完整的 URL 由六个部分构成:
https://www.example.com:443/docs/index.html?from=notes#title| 部分 | 内容 | 作用 |
|---|---|---|
| 协议 | https:// | 决定通信走 HTTP 还是 HTTPS,后者加密 |
| 域名 | www.example.com | 要访问的主机名,需通过 DNS 解析为 IP |
| 端口 | 443 | 默认 HTTPS 是 443、HTTP 是 80,可省略 |
| 路径 | /docs/index.html | 服务器内部的资源位置 |
| 查询参数 | ?from=notes | 传给后端的额外参数,搜索/过滤/分页常用 |
| 片段 | #title | 浏览器内部使用,跳转到页面锚点,不发送到服务器 |
路径不参与 DNS 解析
一个容易被忽略的关键事实:DNS 只把域名翻译成 IP,URL 中的路径和后续字段不参与 DNS 解析。www.example.com/docs 与 www.example.com/api 对 DNS 来说完全相同,返回同一个 IP——路径的处理发生在服务器收到请求之后,Web 服务根据路径将请求分流到不同处理逻辑。
这一认知决定了排查方向:同一域名下不同路径访问异常,问题不在 DNS,而在 Web 服务的路由配置或后端实现。

片段不发送到服务器
URL 中 # 之后的内容(片段标识符)完全由浏览器在客户端处理,不会发送到服务器。在浏览器抓包(Network 面板)中观察到的请求路径不包含 #xxx。这意味着:基于片段的页面跳转(单页应用的路由)不会触发服务器请求,服务器日志中也不会出现这部分内容。
二、DNS 解析
机器之间通信使用的是 IP 地址,域名是为方便人类记忆而设计的。浏览器拿到域名后,第一步就是查询该域名对应的 IP——这个过程称为 DNS(Domain Name System)解析。DNS 的作用类似电话查号台:用户记得住名称,但通信需要号码,DNS 完成两者之间的翻译。
常见 DNS 记录类型
| 记录类型 | 返回内容 | 典型用途 |
|---|---|---|
| A | IPv4 地址 | 最常见,绝大多数业务域名使用 A 记录 |
| AAAA | IPv6 地址 | IPv6 网络下使用 |
| CNAME | 另一个域名 | 接入 CDN 的业务域名几乎都使用 CNAME |
| MX | 邮件服务器域名 | 邮件服务相关 |
| TXT | 任意文本 | 域名所有权验证、SPF/DKIM 等 |
| NS | 该域名的权威 DNS 服务器 | 域名委派管理 |
CDN 场景下为何使用 CNAME
接入 CDN 的网站,业务域名通常 CNAME 到 CDN 厂商提供的域名,而非直接配置 A 记录。原因:CDN 厂商的边缘节点 IP 是动态分配的——根据用户地理位置就近返回最优节点 IP,且节点列表频繁变化。业务方无法预测和写死这些 IP,只能通过 CNAME 把解析过程委托给 CDN,由 CDN 在解析时决定返回哪个边缘节点的 IP。
典型的解析链:
www.example.com CNAME example.com.cdn-provider.net
example.com.cdn-provider.net A 203.0.113.42 (北京用户解析得到的)
example.com.cdn-provider.net A 198.51.100.13 (上海用户解析得到的)
DNS 失败的两类判定信号
| 浏览器错误 | 含义 | 排查方向 |
|---|---|---|
DNS_PROBE_FINISHED_NXDOMAIN | 域名不存在 | 域名拼写错误、解析记录未配置、域名已过期 |
DNS_PROBE_FINISHED_NO_INTERNET | 本机无法访问 DNS 服务器 | 本机网络故障、DNS 服务器不可达 |
DNS 失败时,请求根本没有到达任何服务器,问题卡在第一步。
三、TCP 连接与 TLS 握手
DNS 解析返回 IP 后,浏览器需要与 IP:端口 建立 TCP 连接。HTTPS 默认端口 443,HTTP 默认端口 80。
端口的作用
端口的存在意义是让一台机器可以同时承载多个网络服务。同一个 IP 上,22 端口运行 SSH、80 端口运行 HTTP、443 端口运行 HTTPS、3306 端口运行 MySQL——通过端口号区分不同服务。这些端口号属于业界约定的"知名端口",变更需要客户端显式指定。
TLS 握手:HTTPS 特有的步骤
HTTPS 在 TCP 连接建立后,还要进行 TLS 握手——客户端验证服务器证书的有效性,双方协商加密参数,后续通信全程加密。这一步可能在以下场景失败:
| TLS 失败现象 | 含义 |
|---|---|
NET::ERR_CERT_DATE_INVALID | 证书已过期或尚未生效(服务器时钟偏差也会触发) |
NET::ERR_CERT_COMMON_NAME_INVALID | 证书的域名与访问的域名不匹配 |
NET::ERR_CERT_AUTHORITY_INVALID | 客户端不信任证书的签发机构 |
NET::ERR_CONNECTION_RESET | TLS 握手过程中连接被重置 |
证书相关的故障在浏览器上表现为红色警告页,直接阻断访问。
连接层错误:REFUSED vs TIMED_OUT
如果连 TCP 连接都建立不起来,浏览器会报:
| 错误 | 含义 | 排查方向 |
|---|---|---|
ERR_CONNECTION_REFUSED | 包到达对方,但端口没有服务监听(或被防火墙 reject) | 服务端确认服务是否启动、端口是否监听 |
ERR_CONNECTION_TIMED_OUT | 包根本没到达对方 | 网络路径、防火墙、安全组、目标主机离线 |
这两个错误反映的是完全不同的故障类别——REFUSED 是立即返回的,说明对方机器在线但服务不通;TIMED_OUT 是几十秒后才返回,说明包根本没到。混淆这两者会让排查方向完全跑偏。

四、HTTP 请求
TCP / TLS 连接建立后,浏览器开始发送 HTTP 请求。HTTP 本质是一个基于文本的协议,规定了客户端和服务器之间如何表达"请求什么"和"返回什么"。
HTTP 请求的核心组成
一个典型 HTTP 请求包含:
GET /docs/index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 ...
Accept: text/html
Cookie: session=abc123
Authorization: Bearer xxx
(POST 请求才有 body)关键字段:
- 方法:
GET(读)、POST(写)、PUT(更新)、DELETE(删除)、HEAD(只看响应头) - 路径:URL 中协议、域名、端口之后的部分
- Host 头:说明访问的是哪个域名
- Header:Cookie、认证信息、内容类型等元数据
- Body:POST/PUT 这类提交数据的请求才有
Host 头的关键作用
同一个 IP 后端可能挂多个站点,服务器靠 Host 头区分。例如 www.example.com 和 api.example.com 可能解析到同一个 IP,但 Nginx 等 Web 服务器根据请求的 Host 头将请求转发到不同的后端应用。
缺失或错误的 Host 头会导致 Nginx 无法判断请求归属,通常返回默认站点或 404。
HTTP 响应的状态码分层
请求发出后,服务器返回响应。HTTP 状态码按数字范围分类:
| 范围 | 类别 | 含义 |
|---|---|---|
| 1xx | 信息性 | 临时响应,客户端继续操作 |
| 2xx | 成功 | 请求被成功处理 |
| 3xx | 重定向 | 资源被移到其他位置 |
| 4xx | 客户端错误 | 请求本身有问题(语法、路径、权限) |
| 5xx | 服务端错误 | 服务器在处理请求过程中出错 |
五、入口层
公网请求进入业务程序之前,通常会经过多层入口组件。完整链路可能包括:
每一层的职责:
- CDN — 静态资源就近分发,减少源站压力
- WAF — Web 应用防火墙,过滤恶意请求(SQL 注入、XSS、爬虫)
- 负载均衡 — 把流量分摊到多个后端实例
- Nginx / Ingress — 反向代理,按域名、路径分发请求
- 后端应用 — 实际处理业务逻辑
小型站点可能只有"云服务器 + Nginx"两层,大型业务系统每一层都是独立的集群。
状态码作为故障分层的线索
5xx 与 4xx 状态码本身就是故障分层的最直接线索:
| 状态码 | 含义 | 问题位置 |
|---|---|---|
| 404 | 资源未找到 | 路径错误、Nginx 路由配置、后端路由 |
| 401 | 未认证 | 用户未登录或 token 无效 |
| 403 | 已认证但无权限 | 授权策略拒绝 |
| 500 | 服务器内部错误 | 后端处理过程中出错(代码异常、数据库异常) |
| 502 | Bad Gateway | 入口层连不上后端(后端进程未启动、端口错、连接被拒) |
| 503 | 服务不可用 | 后端实例不可用、过载、健康检查失败 |
| 504 | Gateway Timeout | 入口层等后端超时 |
500 与 502 的本质区别
500 与 502 经常被混淆,但反映完全不同的问题:
- 500 — 后端收到了请求,但在处理过程中报错(代码异常、SQL 错误、外部 API 调用失败)。排查方向是后端应用日志——日志中通常有完整的异常堆栈。
- 502 — 入口层根本没有连上后端。排查方向是入口层(Nginx/Ingress)的 error log,典型错误:
connect() failed (111: Connection refused)— 后端端口没有服务监听no live upstreams while connecting to upstream— 所有后端实例健康检查失败upstream prematurely closed connection— 后端进程崩溃了
混淆这两个状态码会让排查方向完全错位——把"后端进程没起来"的 502 当成"代码 bug"的 500 去查应用日志,显然找不到结果。

六、页面资源加载
服务器返回 HTML 后,浏览器才开始真正"打开"这个页面。HTML 中引用的 CSS、JavaScript、图片、字体等资源,浏览器会再发起新的请求去拉取。一个网页打开背后,Network 面板里通常有几十甚至上百个请求。
前后端分离应用的访问链路更长
前后端分离架构下,首次请求往往只返回一个 index.html 骨架和若干 JS/CSS 文件。真正的业务数据通过 JavaScript 在浏览器运行后,再调用 /api/... 接口获取。这意味着:
- 页面打开慢,可能不是初始 HTML 慢,而是后续某个 JS bundle 过大或某个 API 请求超时
- 用户看到"页面打开但内容一直转圈",通常是 API 请求(后端或数据库)的问题,而不是 HTML 自身的问题
完整的请求链路时序:
七、按现象快速分层定位
排查"网站访问异常"的核心方法是根据用户侧的现象,直接定位到大概率的故障层,而不是从头开始逐层查。
| 用户侧现象 | 可能位置 | 排查方向 |
|---|---|---|
浏览器报 DNS_PROBE_FINISHED_NXDOMAIN | DNS | 域名拼写、解析记录、本机 DNS 缓存 |
浏览器报 ERR_CERT_*(红色警告页) | TLS | 证书有效期、域名匹配、签发机构信任 |
ERR_CONNECTION_REFUSED(立即返回) | 连接层 | 服务进程未启动、端口监听错误 |
ERR_CONNECTION_TIMED_OUT(几十秒后返回) | 网络层 | 防火墙、安全组、路由、对方主机离线 |
| 返回 404 | 路由层 | Nginx 路由配置、后端路由表 |
| 返回 401 | 认证 | 登录失效、token 过期 |
| 返回 403 | 权限 | 用户角色、资源 ACL |
| 返回 500 | 后端应用 | 应用日志中的异常堆栈 |
| 返回 502 | 入口到后端 | 入口层(Nginx)的 error log |
| 返回 503 | 后端容量/健康检查 | 实例数量、健康检查状态、限流策略 |
| 返回 504 | 后端响应慢 | 后端慢查询、外部 API 调用超时 |
| 页面打开但内容转圈 | 接口层 | 浏览器 Network 看具体哪个 API 请求异常 |
这套"按现象定位"的方法是网站故障排查的基础。后续每一讲会展开具体某一层的实现细节、配置方式、典型故障——本讲建立的是整体的层次认知,后续排查时回到这个全景图,知道每一步在查什么、为什么这么查。