先记住这个答案
完整链路是:客户端先查浏览器缓存、操作系统缓存和 hosts 文件,未命中就把请求发给配置的递归解析器(如运营商或 8.8.8.8)。客户端到递归解析器这一段是递归查询,客户端只发一次请求、等待最终答案,责任全在解析器身上。递归解析器再向根服务器、顶级域服务器、权威服务器逐级发起迭代查询,每一级不代查,只返回下一级该问谁。拿到权威答案后解析器按 TTL 缓存并返回给客户端。区分两者的关键是谁承担继续追问的责任。
- 本地缓存未命中才进入外部解析链路
- 递归由解析器负责到底,迭代逐级指路
- 根和顶级域服务器只做迭代不代查
从缓存到权威服务器的完整链路
一次解析以 www.example.com 为例:先查浏览器 DNS 缓存,再查操作系统缓存(如 nscd、mDNSResponder)和 /etc/hosts。全部未命中后,请求被发往系统配置的递归解析器。这一步是递归查询,客户端只发一个请求就等最终 IP,不再参与后续过程。
递归解析器自己缓存未命中时,先问 13 组根服务器之一,根返回 .com 顶级域服务器地址;再问顶级域服务器,得到 example.com 权威服务器地址;最后问权威服务器拿到 A 记录。这三跳是迭代查询,因为每一级都不替它继续查,只告知下一跳。解析器按 TTL 缓存结果后应答客户端。
内网服务迁移时的解析排障
某公司将 api.internal.example.com 从旧机房迁移,权威记录已改为新 IP,但部分员工仍连旧地址。排查链路:dig @8.8.8.8 返回新 IP 说明权威和公共链路正常,而员工走的企业内网递归解析器仍返回旧 IP,原因是其缓存的旧记录 TTL 尚未过期。
处理方式是等待 TTL 到期或在解析器上主动刷新缓存(如 rndc flush),并在下次迁移前 24 小时把该记录 TTL 从 86400 降到 300。决策依据是:递归解析器的缓存决定了客户端实际看到的答案,改权威记录不等于改全网视图,迁移窗口必须由 TTL 提前规划。
这条链路在什么条件下会失效
链路描述默认各级缓存可旁路、应答未被篡改。实际中 TTL 未过期时权威记录的变更不可见;企业 Split-horizon DNS 会让同一域名在内网和外网返回不同答案;运营商可能劫持 53 端口把查询重定向到自己的解析器,此时迭代链路根本走不到真正的权威服务器。
验证手段是逐层比对:dig @根服务器、dig @TLD、dig @权威 分别执行迭代查询,定位答案在哪一级开始分叉。代价是绕过缓存的逐层查询延迟更高、且部分权威服务器限速。对劫持可改用 DoH 走加密通道,但这改变了链路本身,属于另一套信任模型。
容易答错的地方
- 认为根服务器会代查整个域名
- 根服务器只做迭代应答,它不知道也不去查
example.com的 A 记录,只返回.com顶级域服务器列表。把代查责任归给根会混淆递归与迭代的边界。 - 认为客户端自己完成多级迭代
- 绝大多数 stub resolver(系统解析库)只发一次递归请求给递归解析器,从不直接联系根或权威服务器。多级迭代发生在递归解析器一侧,不是客户端。
面试官还会怎么问?
为什么客户端到递归解析器不也设计成迭代?
因为客户端是资源受限的终端,让它维护根服务器列表并逐跳重试成本高、复用率低。递归解析器集中服务大量客户端,缓存共享后绝大多数查询可直接命中,迭代代价由解析器摊销。
dig 命令默认发起的是递归还是迭代查询?
dig example.com 默认向系统配置的递归解析器发递归查询,头部会带 RD 标志。加 +norecurse 可观察解析器不代查时的行为,用 +trace 则能让 dig 自己模拟从根开始的完整迭代过程。
解析过程中哪一环最容易成为延迟瓶颈?
冷缓存时跨洲访问根或权威服务器的 RTT 是主要开销,完整迭代通常需两到三次往返。本地和递归解析器缓存命中时延迟可降到毫秒级以下,这也是预连接和 dns-prefetch 的优化依据。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。