一文看懂 DNS 解析全流程(工程视角版)
一、DNS 是什么?先说清楚它解决什么问题
DNS(Domain Name System)解决的是一个非常简单、但极其重要的问题:
把人类可读的域名,转换为机器可通信的 IP 地址。
例如:
text
www.baidu.com → 180.101.xx.xx
DNS 本质上是一个分布式、分层、可缓存的命名系统。
二、DNS 解析涉及的核心角色
在理解流程之前,必须先分清几个角色,否则后面一定会混:
1️⃣ 客户端(Stub Resolver)
- 浏览器 / 操作系统中的 DNS 客户端
- 功能非常简单:发请求、收结果
- 不具备完整解析能力
2️⃣ 递归解析器(Recursive Resolver)
-
通常是:
- 运营商 DNS
- 公共 DNS(8.8.8.8 / 114.114.114.114)
-
核心职责:
客户端只问一次,它负责跑完整个解析流程,返回最终结果
DNS 中所谓的"递归",指的是查询语义和职责委托,而不是编程意义上的函数递归。
3️⃣ 权威 DNS(Authoritative DNS)
- 对某个域(zone)拥有最终解释权
- 只回答自己负责的数据
- 不帮你继续查
三、DNS 查询的两种语义:递归 vs 迭代
这是 DNS 的核心概念之一。
🔹 递归查询(Recursive Query)
含义是:
"你别管中间过程,直接给我最终答案。"
- 发生在:
客户端 → 递归解析器 - 通过 DNS 报文中的 RD(Recursion Desired) 位表达
🔹 迭代查询(Iterative Query)
含义是:
"我不知道答案,但我告诉你下一步该问谁。"
- 发生在:
递归解析器 → 根 / TLD / 权威 DNS
四、DNS 解析的完整流程(无缓存理想情况)
下面以解析 www.baidu.com 为例,忽略缓存,展示最完整的链路。

第一步:客户端发起递归查询
text
客户端 → 本地递归 DNS
请求内容大致是:
"请帮我解析
www.baidu.com,我需要最终结果。"
客户端从此不再关心中间过程,只等待返回。
第二步:递归解析器查询根服务器
text
递归 DNS → 根 DNS
- 全球逻辑上只有 13 组根服务器(A--M)
- 实际通过 Anycast 部署了大量实例
根服务器不会返回 IP,而是返回:
text
".com 的顶级域名服务器在哪里"
第三步:查询顶级域名服务器(TLD)
text
递归 DNS → .com TLD DNS
.com 服务器不会返回 www.baidu.com 的 IP,而是返回:
text
"baidu.com 的权威 DNS 是哪些"
返回内容主要是:
- NS 记录(权威服务器是谁)
- 以及必要时的 glue 记录(权威服务器的 IP)
第四步:查询权威 DNS
text
递归 DNS → baidu.com 权威 DNS
这一步,递归解析器终于问到了真正负责该域的服务器。
权威 DNS 返回:
www.baidu.com的 A / AAAA 记录- 或者 CNAME(需要继续解析)
这一步返回的结果是最终权威答案。
第五步:结果返回与缓存
text
权威 DNS → 递归 DNS → 客户端
同时:
- 递归 DNS 按 TTL 缓存结果
- 客户端 / OS / 浏览器也可能缓存
这一步是 DNS 高性能的关键。
五、NS 与 Glue 记录的作用(关键但常被忽略)
NS 记录
- 表示:某个域由哪些权威 DNS 负责
例如:
text
baidu.com. NS ns1.baidu.com.
Glue 记录
- 当 NS 的名字本身位于被委派域内部时
- 上级 DNS 会"顺手"返回 NS 的 IP
作用只有一个:
防止解析权威 DNS 名字时产生死循环
Glue 不是最终权威数据,只是解析链路中的"连接器"。
六、DNS 缓存机制(为什么它这么快)
DNS 性能的核心,不是服务器多强,而是缓存策略。
缓存可能存在于:
- 递归解析器(最重要)
- 操作系统
- 浏览器
缓存由 TTL 控制:
- 权威 DNS 设置 TTL
- 表示"这个结果可以信多久"
七、为什么普通用户感受不到这些复杂性?
因为:
- 你只发出 一次请求
- 递归 DNS 帮你跑完所有流程
- 你只看到最终结果
这正是 DNS 设计的初衷:
把复杂性集中在少数节点,换取整个互联网的可用性和性能。
八、一段面试级总结(可直接背)
DNS 解析过程中,客户端向递归解析器发起递归查询,请求返回最终结果;递归解析器在本地无缓存的情况下,通过对根服务器、顶级域名服务器以及权威 DNS 进行迭代查询,逐级定位目标域名的权威服务器并获取最终解析记录,结果按 TTL 缓存后返回客户端。
九、结语
DNS 并不是一个"复杂协议",
它真正厉害的地方在于:
- 清晰的分层设计
- 极强的缓存友好性
- 对失败和延迟的高度容忍
这也是为什么它能在几十年内支撑整个互联网,而核心设计几乎没有改变。