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
目录