文章

DNS解析与CDN加速原理深入解析

DNS 是把域名翻译成 IP 的分布式"电话簿",CDN 是把静态资源缓存到离用户最近节点的加速网络。 从输入 URL 到页面显示、CDN 回源与命中率,是前端性能与网络面试的高频题。

DNS解析与CDN加速原理深入解析

一句话概括

DNS(Domain Name System)干一件事:把人能记住的 www.example.com 翻译成机器要的 IP 93.184.216.34,是整个互联网的电话簿。没有它,换一次服务器 IP 全互联网都找不到你。

CDN(Content Delivery Network)则是把你的静态资源(js/css/图片/视频)缓存到全球边缘节点,让用户从最近的节点取,而不是跨半个地球打到你源站。延迟能从几百毫秒降到几十毫秒。

两者是前端性能优化的地基:DNS 决定”第一次握手前的耗时”,CDN 决定”资源下载的耗时”。面试常从”输入 URL 到页面显示”一路问到 CDN 回源、缓存命中率。下面把链路和坑讲清。

核心知识点

1. DNS 解析全流程(递归查询)

1
2
3
4
5
6
7
8
9
10
浏览器输入 www.example.com
  ├─ 1. 浏览器 DNS 缓存(命中即返回,Chrome 默认约 60s)
  ├─ 2. 操作系统缓存(hosts 文件优先级最高,其次系统缓存)
  ├─ 3. 本地 DNS(ISP / 8.8.8.8 / 223.5.5.5)查询
  │     ├─ 有缓存 → 直接返回
  │     └─ 无缓存 → 递归问:
  │          根服务器 "."        → "去问 .com"
  │          顶级域 TLD ".com"   → "去问 example.com 的权威服务器"
  │          权威服务器          → "答案是 93.184.216.34"
  └─ 4. 结果逐层缓存(按 TTL)→ 浏览器拿到 IP → 开始 TCP 连接

耗时参考:浏览器/系统缓存命中≈1–10ms;完整递归≈30–200ms。所以”减少 DNS 查询次数”本身就是优化。

2. DNS 记录类型与 CDN 的钩子

类型作用示例
A域名 → IPv4example.com → 93.184.216.34
AAAA域名 → IPv6example.com → 2606:...
CNAME域名 → 另一个域名(别名)cdn.example.com → xxx.cdn.cloudflare.net
MX邮件服务器@ → mail.example.com
TXT文本(SPF/DKIM 校验)v=spf1 include:_spf.google.com ~all
NS指定域名服务器example.com → ns1.example.com

CDN 的核心钩子就是 CNAME:你把 cdn.example.com CNAME 到 CDN 厂商的域名,CDN 的权威 DNS 再根据用户 IP(或 ECS 扩展)返回最近的边缘节点 IP——这就是”智能调度”。

3. DNS 缓存层级与 TTL

1
2
www.example.com.  3600  IN  A  93.184.216.34
                   ↑ TTL = 3600 秒,各级 DNS 按它缓存
1
2
3
浏览器缓存  ← 约 60s(Chrome 默认,不完全等于 TTL)
操作系统缓存 ← 按 TTL
本地 DNS    ← 严格按 TTL(这里是全局缓存主力)

TTL 是双刃剑:

  • 静态资源:用长 TTL(如 86400s),缓存命中率高
  • 要切 CDN / 换 IP:先调短 TTL(如 300s),切换完成再调回长 TTL,避免旧 IP 缓存太久

4. CDN 工作原理与回源

1
2
3
4
5
6
用户请求 https://cdn.example.com/style.css
  ├─ DNS 解析 → 返回最近的边缘节点 IP
  ├─ 节点有缓存 → 直接返回(缓存命中 ✅)
  └─ 节点无缓存 → 回源(去源站拉)→ 缓存到本地 → 返回(缓存未命中 ❌)

后续同区域用户访问同一资源 → 直接命中边缘缓存

回源(Origin Pull)触发场景:第一次冷启动、TTL 过期、源站手动刷新、动态内容不缓存。回源是要加延迟的,所以”命中率”是 CDN 第一指标(好 >90%,差 <70%)。

1
2
3
# 源站用这些头告诉 CDN 怎么缓存
Cache-Control: public, max-age=31536000        # 浏览器+CDN 都缓存 1 年
Cache-Control: s-maxage=86400                   # 仅覆盖 CDN 侧缓存(1 天)
1
2
3
4
5
6
7
# 源站 Nginx:静态资源长缓存,HTML 不缓存(便于发版)
location ~* \.(js|css|png|webp|woff2)$ {
    add_header Cache-Control "public, immutable, max-age=31536000";
}
location ~* \.html$ {
    add_header Cache-Control "no-cache, must-revalidate";
}

5. 前端能做的 DNS 优化

1
2
3
4
5
6
<head>
  <!-- dns-prefetch:提前只做 DNS 解析(最轻量) -->
  <link rel="dns-prefetch" href="//api.example.com">
  <!-- preconnect:DNS + TCP + TLS 全预建(确定要访问时用) -->
  <link rel="preconnect" href="https://api.example.com" crossorigin>
</head>
1
2
3
dns-prefetch:只解析 DNS
preconnect  :DNS + TCP + TLS
区别:确定会访问的域用 preconnect,可能访问的用 dns-prefetch,别无脑全 preconnect(占连接资源)

其实你每天都在用

  • 输入网址后那几百毫秒:浏览器先走完上面整套 DNS 递归,拿到 IP 才连 TCP,慢的根因常在 DNS
  • ping / nslookup / dig:排查”域名解析不出来”的标配命令
  • 刷新页面 js/css 没更新:八成是 CDN 缓存没清,得在 CDN 后台 Purge 或给文件名加 hash 版本号
  • cdn.jsdelivr.net、cdnjs.cloudflare.com:你引的第三方库就是 CDN,自动就近
  • <link rel="dns-prefetch">:大站在 head 里提前解析 API/CDN 域名,省掉首屏 DNS 等待
  • 切服务器 IP 后部分地区半天不生效:TTL 还没过期,老 IP 还在缓存,所以换 IP 前要先降 TTL
  • 视频/大文件卡顿:可能命中了离你远的节点,CDN 调度没选对(或节点负载高)

常见误解(FAQ)

❌ 误区一:”DNS 解析就是查一次就完事,慢不到哪去”

整套递归要层层问根/TLD/权威服务器,完整未命中时 30–200ms 真不少;而且每引一个不同域(API、CDN、统计)就多一次。所以 dns-prefetch / preconnect 才有价值,把”隐形成本”提前吃掉。

❌ 误区二:”CDN 就是把文件复制一份到别的地方,永远比源站快”

错。CDN 有缓存未命中就要回源,此时反而比直连多一跳。命中率才是关键。另外源站响应慢、TTL 设太短、频繁发版,都会拉低命中率、放大回源。

❌ 误区三:”改了文件,CDN 马上就该显示新版”

不会。CDN 按 TTL 缓存,没到过期时间、也没手动 Purge,用户看到的还是旧文件。正确姿势:静态资源文件名带 hash(如 app.a1b2c3.js),内容变了文件名就变,CDN 当新资源缓存,旧的可安心长缓存。

❌ 误区四:”CDN 只加速图片/js,跟 API 没关系”

传统 CDN 确实主打静态。但现在有动态加速(DCDN):API 请求也走边缘节点,靠 BGP 优化路由、TCP/TLS 复用缩短到源站路径(不缓存内容,只优化网络)。实时性要求高的接口也能受益。

一句话总结

DNS 是把域名翻成 IP 的分布式电话簿,解析慢一拍首屏就慢一拍;CDN 用边缘缓存把资源送到用户家门口,命中率决定它值不值。前端要做的,是长缓存静态资源、用 dns-prefetch/preconnect 预解析、用文件 hash 解决更新失效——把这两层地基打稳,性能才有底气。

本文由作者按照 CC BY 4.0 进行授权