DNS 解析过程与优化

DNS 递归/迭代查询原理及前端 DNS 预解析优化

问题

解释 DNS 解析的递归查询和迭代查询过程,以及前端如何通过 DNS 预解析进行优化。

解答

DNS 解析过程

当浏览器访问 www.example.com 时,DNS 解析流程如下:

浏览器 → 本地 DNS 缓存 → 系统 hosts → 本地 DNS 服务器 → 根域名服务器 → 顶级域名服务器 → 权威域名服务器

递归查询

客户端只发一次请求,DNS 服务器负责完成全部查询并返回最终结果。

客户端 ──请求──→ 本地 DNS 服务器 ──请求──→ 其他 DNS 服务器
       ←──结果──                ←──结果──

客户端问本地 DNS:“www.example.com 的 IP 是什么?“,本地 DNS 负责找到答案后返回。

迭代查询

DNS 服务器返回下一个应该查询的服务器地址,由请求方继续查询。

本地 DNS ──→ 根服务器      返回:去问 .com 服务器
         ──→ .com 服务器   返回:去问 example.com 服务器
         ──→ 权威服务器    返回:IP 是 93.184.216.34

完整流程示例

1. 浏览器检查自身 DNS 缓存
2. 检查操作系统 DNS 缓存
3. 检查 hosts 文件
4. 向本地 DNS 服务器发起递归查询
5. 本地 DNS 服务器进行迭代查询:
   - 询问根服务器 → 获得 .com 服务器地址
   - 询问 .com 服务器 → 获得 example.com 权威服务器地址
   - 询问权威服务器 → 获得最终 IP
6. 本地 DNS 服务器缓存结果并返回给浏览器

DNS 预解析 (dns-prefetch)

提前解析将要访问的域名,减少用户点击链接时的等待时间。

<!-- 基本用法 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="dns-prefetch" href="//api.example.com">
<link rel="dns-prefetch" href="//fonts.googleapis.com">

<!-- 配合 preconnect 使用,同时完成 DNS + TCP + TLS -->
<link rel="preconnect" href="https://cdn.example.com">

使用场景

<!DOCTYPE html>
<html>
<head>
  <!-- 预解析第三方资源域名 -->
  <link rel="dns-prefetch" href="//cdn.bootcdn.net">
  <link rel="dns-prefetch" href="//hm.baidu.com">
  
  <!-- 预解析即将跳转的页面域名 -->
  <link rel="dns-prefetch" href="//other-site.com">
</head>
<body>
  <a href="https://other-site.com/page">跳转链接</a>
</body>
</html>

通过 HTTP 响应头设置

Link: <https://cdn.example.com>; rel=dns-prefetch

其他 DNS 优化策略

<!-- 1. 减少域名数量,合并资源到同一域名 -->

<!-- 2. 使用 CDN,利用就近节点 -->

<!-- 3. 设置合理的 DNS TTL -->

<!-- 4. 资源预加载组合使用 -->
<link rel="dns-prefetch" href="//example.com">  <!-- 仅 DNS -->
<link rel="preconnect" href="//example.com">    <!-- DNS + TCP + TLS -->
<link rel="prefetch" href="//example.com/data"> <!-- 预获取资源 -->

关键点

  • 递归查询:客户端发一次请求,DNS 服务器负责找到最终结果
  • 迭代查询:DNS 服务器返回下一步查询地址,由请求方继续查询
  • dns-prefetch:提前解析域名,适用于第三方资源和即将访问的页面
  • preconnect:比 dns-prefetch 更进一步,同时完成 DNS、TCP、TLS
  • 优化原则:减少域名数量、使用 CDN、合理设置 TTL