一、先说清 DNS 是什么
-
域名的分布式数据库,做"域名→IP"的映射,分层:根(root ".")→ 顶级域(.com/.cn)→ 权威(nameserver,如 baidu 自己的 NS)。
-
常见记录:A(IPv4)、AAAA(IPv6)、CNAME(别名)、NS(谁负责这个域)、MX(邮件)、TXT、PTR(反解)、SOA。
二、递归 vs 迭代(最容易答错的点)
-
递归查询:客户端把问题丢给本地 DNS 并加 RD=1,"我要最终结果"。本地 DNS 有责任跑完全程,只回最终答案(或 NXDOMAIN)。
-
迭代查询:本地 DNS 去问根服务器,根只回"你去问 .com 的 NS";问 .com 的 TLD,它回"去问 baidu.com 的权威 NS";问权威,才拿到 www.baidu.com 的记录。每一跳都只是"下一站是谁"。
-
所以整条链上是:对客户端=递归;本地 DNS 对公网=迭代。中间若前面还有转发器(forwarder)或 DNS 缓存,那就是"递归→转发→再迭代"。
三、内网 DNS 和公网 DNS
-
内网 DNS:企业/学校/路由器上自建或下发的 DNS(私网地址,如 10.x / 192.168.x),只在内网可达。作用:① 解析内网域名(只在内网有意义)② 做转发 ③ 智能选路(内外网同名给不同结果,split-horizon DNS)④ 缓存提速。
-
公网 DNS:运营商 DNS(如 114.114.114.114)和公共 DNS(223.5.5.5 阿里、119.29.29.29 腾讯、8.8.8.8、1.1.1.1)。
-
你这台机器的实测:默认 DNS = 192.168.43.1(192.168.43.x 是手机热点的典型网段),也就是网关上的转发器,它再往上问运营商;nslookup 里那个 "bogon" 是它没有 PTR 记录的正常现象。
四、CDN 的原理(和你实测到的证据)
-
做法:在全国/全球布边缘节点,把内容缓存到离用户近的节点;再用DNS 智能调度(GSLB)把用户引到最近节点,配合 anycast + 边缘缓存,降低 RTT 和回源压力。
-
识别特征就是 CNAME:域名先 CNAME 到 CDN 厂商的域名,权威 DNS 再按"它看到的你的位置"返回节点 IP。实测:
-
www.baidu.com → CNAME www.a.shifen.com → A 110.242.69.21 / 110.242.70.57(百度自建)
-
www.taobao.com → CNAME www.taobao.com.danuoyi.tbcache.com → 117.9.78.93/94(淘宝 CDN)
-
www.jd.com → CNAME www.jd.com.gslb.qianxun.com → www.jd.com.s.galileo.jcloud-cdn.com → A 123.6.77.65
-
最值得记的实测对比(同一个域名、换 DNS 就换了节点):
-
走本机默认 DNS(内网/运营商侧):www.jd.com → 123.6.77.65(河南的 123.6.x 网段,就近)
-
走 8.8.8.8:www.jd.com → jd-abroad.cdn20.com → 42.231.143.224 / 123.6.17.57 → 被调度到"海外"节点
→ 结论:CDN 调度的依据是"DNS 解析器眼里的你",不是真实的你。权威 DNS 看不到客户端 IP 时(境外公共 DNS 通常不传 ECS),只能按解析器出口 IP 定位,于是把你调去远处。这正是"国内用 8.8.8.8 解析国内 CDN 反而慢"的原因。
-
TTL 也是证据:百度 A 记录 TTL 只有 15~114 秒(便于随时换节点);而你本地 DNS 返回的 CNAME TTL 是 818 秒 ------ 说明它自己缓存的剩余时间。
-
缓存分层:浏览器缓存 → OS 缓存 → 内网/运营商 DNS 缓存 → 权威;边缘节点缓存未命中才回源(带 Host 回源站),源站再查库/渲染。
五、敲下 www.baidu.com 到页面出现,完整发生了什么
0 浏览器预处理:补全 scheme(https://)、解析 URL 取出 host、HSTS 表检查(命中就强制 https)、查浏览器自己的 DNS 缓存(chrome://net-internals/#dns)。
1 DNS 阶段(递归+迭代,就是上面第二三条)
浏览器缓存未命中 → 交给系统 stub(Windows DNS Client)→ 查 hosts(C:\Windows\System32\drivers\etc\hosts)→ 查系统 DNS 缓存(ipconfig //displaydns 能看)→ 没有就发给首选 DNS(你这里是
192.168.43.1),随机源端口,问 www.baidu.com 的 A/AAAA,RD=1。
本地 DNS 缓存未命中 → 从根开始迭代:根 → .com NS → baidu.com 权威 NS → 权威回 "www.baidu.com CNAME www.a.shifen.com",再解析 www.a.shifen.com 拿 A/AAAA。
实测结果:CNAME www.a.shifen.com;A 110.242.69.21、110.242.70.57;AAAA 2408:871a:2100:1b23:0:ff:b07a:7ebc。本地 DNS 按 TTL 缓存后回给系统,系统再回给浏览器。
2 建连接:按 AAAA 优先/IPv4 逐个尝试,TCP 三次握手(你机器上 ping 走的就是上面那条 IPv6,RTT 29~55ms);然后 TLS 握手(ClientHello → ServerHello + 证书链 → 密钥协商 → Finished,SNI 携带
www.baidu.com、ALPN 协商 h2),校验证书、可能复用会话票据。
3 发 HTTP 请求:HTTP/2 多路复用,GET /,带 Host/UA/Accept/Cookie/Accept-Encoding(br,gzip);如果打到的就是 CDN 边缘且内容命中,边缘直接返回。
4 服务器/CDN 响应:边缘未命中 → 回源到源站机房 → 应用逻辑 → 数据库 → 生成 HTML;返回 200(可能 gzip/br 压缩)、Cache-Control、Set-Cookie 等;也可能先来一个 301/302(如 http 跳 https),于是上面流程再走一遍。
5 浏览器渲染(这时候你才"看到页面"):解析 HTML 建 DOM → 遇到 <link>/<script>/<img> 再发起新一轮请求(静态域名如 ss0.bdstatic.com 等,通常已有 DNS 缓存/preconnect,资源多来自 CDN 边缘)→ CSS 建 CSSOM → JS
下载执行(可改 DOM)→ DOM+CSSOM 合成渲染树 → Layout 布局 → Paint 绘制 → Composite 合成上屏。期间产生 TTFB、白屏时间、DOMContentLoaded、onload 等指标。
6 收尾:结果写入各级缓存(HTTP 缓存、TLS 会话缓存、DNS 缓存按 TTL),下次访问从第 2 步甚至第 0 步的缓存直接开始。
六、你自己可以复现的验证命令(都在你机器上跑过)
ipconfig //all | grep -i DNS 看本机 DNS 是谁
nslookup www.baidu.com 看 CNAME + A/AAAA
nslookup -type=CNAME www.baidu.com 只看别名链
powershell "Resolve-DnsName www.baidu.com -Type A | ft Name,Type,TTL,IPAddress"
powershell "Resolve-DnsName www.jd.com -Server 8.8.8.8 -Type A | ft ..." 对比公网 DNS 的调度差异
ipconfig //displaydns | grep -i baidu 看本地 DNS 缓存里已有的记录
ping www.baidu.com 看就近节点的 RTT
curl -v -o /dev/null https://www.baidu.com 看 DNS/TCP/TLS/HTTP 全过程
一句话串起来:浏览器缓存/OS 缓存/hosts 都没命中 → 递归问本地(内网) DNS → 它迭代问根/TLD/权威拿到 CNAME 和 A/AAAA(权威按解析器位置做 CDN 调度,所以不同 DNS 解析结果不同)→ 系统按 TTL 缓存并回给浏览器 → TCP + TLS 建连(IPv6
优先,你这边走 2408:... )→ HTTP/2 请求打到 CDN 边缘(命中直接回,未命中回源)→ HTML 返回后浏览器再对静态资源重复 DNS/TCP/TLS/HTTP 并逐步渲染上屏。