DNS:域名是怎么变成 IP 地址的
为什么要用域名而不是直接记住 IP
用户在浏览器里输入 www.example.com,但网络层的 TCP 连接需要的是 IP 地址。域名只是给人看的,机器之间真正通信靠的是 IP。DNS,全称 Domain Name System,就是负责把域名翻译成 IP 地址的系统。
为什么不让用户直接记 IP?原因很直观:
- IP 地址难记,尤其 IPv6 地址更长。
- 同一域名背后的服务器 IP 可能经常变化,比如迁移机房、切换 CDN。
- 一个域名可以对应多个 IP,实现负载均衡和容灾。
所以 DNS 的价值不只是“查表”,而是提供了一层域名到 IP 的可配置映射。这层映射把“用户记忆的稳定标识”和“底层会变的网络地址”解耦了。理解了这一点,后面很多生产实践——CDN、灰度发布、故障切换——本质上都是在改这张映射表。
域名的结构是分层的
要理解 DNS,先要理解域名本身的结构。域名不是一串扁平字符串,而是有层级的,每一级由 . 分隔,并且从右往左读。
www.example.com.
│ │ │ │
│ │ │ └── 根域(root),通常省略,但实际存在
│ │ └────── 顶级域(TLD),如 com、cn、org
│ └────────────── 二级域(SLD),如 example
└────────────────── 主机名(host),如 www
一个完整域名末尾其实有一个隐含的根域名 .,比如 www.example.com.。日常书写时这个点通常被省略,但它在 DNS 协议里是存在的,代表整个域名空间的起点。
从右往左的层级意味着域名空间是一棵倒置的树:根在最上面,下面是顶级域,再往下是二级域、子域,最后是主机名。这套分层结构,直接决定了后面“多级域名服务器”的组织方式——每一层域名,都由对应的一层服务器来管理。
DNS 服务器的多级体系
域名分层,对应的服务器也分层。DNS 是分布式系统,没有任何一台服务器保存全世界的所有域名记录,而是按层级分散管理。核心分三级:
根域名服务器(Root Server)
根域名服务器是解析的入口,负责管理顶级域。它不直接告诉你要查的域名对应哪个 IP,而是告诉你去问哪个顶级域服务器。
全世界有 13 组根服务器,编号从 a.root-servers.net 到 m.root-servers.net。这里的“13 组”不是“13 台”,每一组背后都用 Anycast 部署了大量镜像节点,分布在世界各地。之所以是 13,是历史原因:早年的 DNS 响应报文走 UDP,受 512 字节限制,13 个根服务器地址刚好能塞进一次响应,不需要走 TCP。
顶级域服务器(TLD Server)
顶级域服务器管理某个顶级域下的所有二级域,例如 .com、.cn、.org。它也不直接返回目标 IP,而是告诉你该域名由哪台权威服务器管理。
顶级域分两类:通用顶级域(gTLD,如 .com、.net、.org)和国家地区顶级域(ccTLD,如 .cn、.jp、.uk)。
权威域名服务器(Authoritative Server)
权威服务器是真正掌握某个域名具体记录的一方。比如 example.com 的 A 记录、CNAME 记录、MX 记录都存在它的权威服务器上。只有权威服务器能给出最终、可信的解析结果,其他缓存里的结果都来源于它。
三级体系可以类比成一次“问路”:
| 角色 | 类比 | 知道什么 |
|---|---|---|
| 根服务器 | 总机/黄页目录 | 顶级域服务器在哪 |
| 顶级域服务器 | 城市分区 | 二级域的权威服务器在哪 |
| 权威服务器 | 小区物业 | 具体房号(IP)是多少 |
除了这三级,还有一个容易被忽略的角色:本地 DNS 服务器(Local DNS Server / Resolver)。它通常由运营商、公司内网或公共 DNS 服务(如 8.8.8.8、114.114.114.114)提供。用户发的解析请求,首先交到它手里,由它代劳跑完整条查询链路。
一次完整的解析过程:递归与迭代
理解了多级服务器,接下来看一次解析请求到底怎么流转。这是 DNS 面试的高频考点,也是最容易混淆的地方:递归查询和迭代查询。
先给出最关键的结论:递归和迭代描述的是“谁来替谁干活”的分工方式,而不是两种互斥的协议。 一次真实解析通常是两者的组合——用户和本地 DNS 之间走递归,本地 DNS 向上查询时走迭代。
递归查询:替你把答案查到底
递归查询的意思是:客户端只发一次请求,剩下的工作全部交给对方,对方必须返回最终结果。
用户 → 本地 DNS:帮我查 www.example.com 的 IP
本地 DNS 收到后,如果自己缓存里没有,就要一路向上查,最后把最终 IP 返回给用户。对用户来说,只需要一次交互,等待一个结果。
这个“替对方跑完全程”的模式就是递归。它的代价是:接收递归请求的一方(本地 DNS)要承担大量的查询工作和中间过程,所以递归查询通常只发生在用户到本地 DNS 这一段。公共 DNS 服务(如 8.8.8.8)就是在这一层提供递归能力。
迭代查询:一层层问下去,每层只给下一步线索
迭代查询的意思是:被问的一方不替你跑完全程,而是告诉你“下一步该问谁”,由你自己继续问。
本地 DNS 向根服务器发起的就是迭代查询,整条链路大致如下:
本地 DNS → 根服务器:www.example.com 在哪?
根服务器 → 本地 DNS:去问 .com 的顶级域服务器,地址是 xxx
本地 DNS → .com 顶级域服务器:www.example.com 在哪?
顶级域服务器 → 本地 DNS:去问 example.com 的权威服务器,地址是 yyy
本地 DNS → example.com 权威服务器:www.example.com 的 IP 是多少?
权威服务器 → 本地 DNS:是 1.2.3.4
本地 DNS → 用户:1.2.3.4
可以看到,本地 DNS 在向上查询时,每问一层,对方只给一个“下一步的线索”,由本地 DNS 自己继续去问下一层。这就是迭代。根服务器和顶级域服务器之所以采用迭代而非递归,是因为它们要服务全球海量请求,不可能替每个请求跑完全程,那会把它们压垮。
两者如何配合
把递归和迭代拼在一起,一次完整解析的真实形态是:
用户 ──递归──> 本地 DNS ──迭代──> 根服务器 ──> TLD 服务器 ──> 权威服务器
(缓存) (逐层返回“下一站”线索)
用一句话概括:用户到本地 DNS 是递归(你替我查到底),本地 DNS 到各级权威是迭代(我替你一层层问)。
面试时经常追问:为什么不能反过来?让用户直接对根服务器做递归,或者让根服务器对用户做递归,都会把压力集中在少数根服务器上。分层 + 迭代,本质是把“全量查询”的负载分散到整个分布式体系里,同时让本地 DNS 的缓存能够命中大部分重复请求。
缓存:为什么解析并没有想象中那么慢
如果每次访问都要从根服务器一路问到权威服务器,DNS 会慢到不可接受,网络也会被查询流量淹没。DNS 靠多级缓存来缓解。
查询结果会被缓存在多个层级:
| 缓存位置 | 说明 |
|---|---|
| 浏览器缓存 | 浏览器自己记住近期解析结果 |
| 操作系统缓存 | 系统层解析缓存 |
| hosts 文件 | 本地静态映射,优先级通常高于 DNS 服务器 |
| 本地 DNS 服务器 | 运营商或公共 DNS 的缓存,命中率最高的一层 |
| 各级服务器 | 权威服务器也依赖上层缓存减少被打爆的压力 |
缓存能命中多久,取决于记录里的 TTL(Time To Live)。权威服务器在返回记录时会附带 TTL,告诉各级缓存“这条记录最多缓存多少秒”。TTL 到期后,缓存失效,下一次查询要重新向上游确认。
TTL 是一把双刃剑:
- TTL 设得太长,缓存命中高、解析快,但改了 IP 后要等很久才能全网生效。
- TTL 设得太短,变更能快速生效,但查询回源更频繁、延迟更高、权威服务器压力更大。
所以生产上 TTL 的取值,通常是“稳定期设长、变更前提前调短”的组合策略。
常见记录类型
DNS 里“域名到 IP”只是最基本的一类记录,实际上记录类型很多。面试常考这几种:
| 记录类型 | 作用 | 示例 |
|---|---|---|
| A | 域名到 IPv4 地址 | www → 1.2.3.4 |
| AAAA | 域名到 IPv6 地址 | www → 2606:4700::... |
| CNAME | 域名别名,指向另一个域名 | www → example.com |
| MX | 邮件服务器 | @ → mail.example.com |
| NS | 该域名由哪台权威服务器负责 | example.com → ns1.example.com |
| TXT | 任意文本,常用于 SPF、域名验证 | TXT → "v=spf1 ..." |
其中 CNAME 在 CDN 接入里用得最多。用户把 static.example.com CNAME 到 CDN 厂商给的域名,CDN 再根据用户地理位置返回就近节点的 IP。这也是为什么同一个域名在不同地区、不同运营商下解析结果可能不同。
要注意一点:CNAME 不能和其他记录共存于同一条名字,而且 CNAME 会带来一次额外的解析跳转。面试时能说清“CNAME 是别名、会多一跳”,就比只会背记录类型强。
DNS 在生产环境中的实践与排查
DNS 不只是面试理论,它直接影响线上可用性和性能。
1. DNS 是首屏性能的隐形成本
页面加载前的 DNS 解析、TCP 连接、TLS 握手,都属于“看不见的耗时”。如果页面依赖多个第三方域名,每个域名都要先解析一遍,首屏就会明显变慢。
对应手段是让浏览器提前解析:
<link rel="dns-prefetch" href="https://cdn.example.com" />
<link rel="preconnect" href="https://cdn.example.com" />
dns-prefetch 只提前做 DNS 解析,preconnect 更进一步,提前把 TCP 和 TLS 也建立好。但别滥用:第三方域名越多、预连接越多,会占用更多资源,要针对真正关键的域名做。
2. 故障切换和负载均衡都靠 DNS
DNS 记录是配置,不是写死的。生产里很多能力都建立在这层映射上:
- 负载均衡:一个域名配置多条 A 记录,DNS 轮询返回不同 IP。
- 就近接入:基于客户端来源返回最近的机房或 CDN 节点 IP。
- 故障切换:某机房故障时,把该机房的 A 记录摘掉,流量自然流向其他 IP。
所以线上“改 DNS 记录”是一件要谨慎的事,它等于在切换流量走向。变更前要确认 TTL、新旧记录切换窗口、以及下游系统是否缓存了旧结果。
3. 域名解析故障怎么排查
遇到“网站打不开”时,DNS 是链路里最早要排查的一环。可以按顺序确认:
- 域名能否解析:用
nslookup或dig看能否拿到 IP。 - 解析结果对不对:是否解析到了错误 IP、是否被劫持或污染。
- 本地缓存是否作祟:改过 DNS 但没生效,先清浏览器和系统缓存。
- TTL 是否过长:变更后要等缓存过期才生效。
- 是否命中了本地 hosts 或公司内网 DNS。
# 指定 DNS 服务器查询,排除本地缓存干扰
dig @8.8.8.8 www.example.com
# 查看完整解析链路
dig +trace www.example.com
dig +trace 会从根服务器开始逐层追踪,非常适合验证“根 → 顶级域 → 权威”这条多级链路是否正常。
4. 常见的两类安全风险
- DNS 劫持:攻击者把域名解析到恶意 IP,用户访问的其实是假网站。这也是 HTTPS + 证书校验存在的原因之一——即使 IP 被指错,证书对不上也会拦截。
- DNS 污染/投毒:向缓存里注入伪造记录,让用户拿到错误结果。
理解这两类风险,才能明白为什么现在有 DoH(DNS over HTTPS)、DoT(DNS over TLS)这类加密 DNS。它们把 DNS 查询本身也加密,防止查询内容被旁路观察或篡改。
面试回答可以怎么组织
如果面试官问“DNS 是怎么工作的”,可以按下面顺序回答:
- DNS 是把域名翻译成 IP 的分布式系统,域名本身是分层结构。
- 服务器也分层:根服务器 → 顶级域服务器 → 权威服务器,各自负责不同层级。
- 一次解析里,用户到本地 DNS 是递归查询,本地 DNS 向上是迭代查询。
- 为了降低延迟和压力,解析结果会按 TTL 在浏览器、系统、本地 DNS 等多级缓存。
- 生产上 DNS 还支撑了负载均衡、就近接入、故障切换,同时也是首屏性能和安全的关注点。
如果被追问“递归和迭代的区别”,核心就一句:递归是对方替你查到底并返回最终结果,迭代是对方只告诉你下一步问谁,由你自己继续问。再补一句“真实解析是两者的组合”,基本就能把这道题答透。
总结
DNS 的主线不复杂:域名分层、服务器也分层,解析时用递归 + 迭代的组合把域名一路查到 IP,再用多级缓存把重复查询消化掉。
- 域名空间是层级结构,从右往左是根域、顶级域、二级域、主机名。
- 服务器分根服务器、顶级域服务器、权威服务器三级,各管一层。
- 递归查询是“替你查到底”,迭代查询是“只告诉你下一站”。
- 一次真实解析是递归 + 迭代的组合,用户到本地 DNS 是递归,本地 DNS 向上是迭代。
- 缓存依赖 TTL 控制,TTL 是延迟与变更生效速度之间的权衡。
- 生产上 DNS 支撑了负载均衡、就近接入、故障切换,也是首屏性能和安全的切入点。
把这条“分层 + 递归迭代 + 缓存”的主线记住,DNS 就不再是一堆孤立的名词,而是一套能串起来讲清楚的机制。