DNS:域名为什么能找到服务器

前面几篇里,无论 TCP 握手还是 TLS 握手,我们都默认"已经知道服务器的 IP"。但你访问网站时输入的是 www.example.com,不是一串 IP 数字。网络设备转发数据靠的却是 IP——那这个从域名到 IP 的翻译,到底是谁、在什么时候、怎么完成的? 这就是 DNS 的工作,也是你每次访问的真正起点。

DNS 表面像"查字典",但如果真只是一本字典,全世界几十亿域名查询全压到一个地方,早就崩了。它实际是一套分层、分布、可缓存的精巧系统。很多人能说出"DNS 把域名解析成 IP",却讲不清那次查询在背后经过了哪几级服务器、谁问谁、谁缓存了什么——而 DNS 故障之所以诡异难查,根子恰恰在这套流程里。

所以这一篇先机制后设计:先完整走一遍一次解析的递归与迭代查询流程,看清每一级服务器各自回答什么、缓存在哪里发生,再回头解释为什么要设计成分层分布式。

一、先看域名的分层结构

理解查询流程前,要先知道域名本身是分层的。读一个域名要从右往左读,每一段对应一个层级:

1
2
3
4
5
www.example.com.
└─┬─┘ └──┬──┘ └┬┘ └─ 根(root,那个常被省略的点)
│ │ └──── 顶级域 TLD(.com)
│ └────────── 二级域(example)
└───────────────── 主机名(www)
  • 最右边的 .(通常省略)是根域
  • .com.org.cn顶级域(TLD)
  • example 是向注册商买的二级域
  • www 是这个域下的具体主机。

这套层级不是为了好看,它直接决定了查询要逐级进行:先问根".com 归谁管",再问 .comexample.com 归谁管”,最后问 example.com 的权威服务器"www 是什么 IP"。层级结构是分布式查询的骨架。

二、三类角色:谁在参与解析

一次解析涉及几类服务器,先分清角色:

  • 递归解析器(Recursive Resolver):通常是你的运营商或公共 DNS(如 8.8.8.8114.114.114.114)提供的。它替客户端"跑腿",负责完成整个查询过程,最后把答案给你。客户端基本只跟它打交道。
  • 根服务器(Root):全球共 13 组(逻辑上),它不知道 example.com 的 IP,但知道".com 的权威服务器(TLD 服务器)在哪"。
  • 顶级域服务器(TLD):管 .com.cn 等。它不知道 www.example.com 的 IP,但知道"example.com 的权威服务器在哪"。
  • 权威服务器(Authoritative)example.com 的实际管理者(如你在云厂商配置的 DNS)。它手握 www.example.com 的真实记录,是最终答案的来源。

关键区分两种查询方式:客户端 → 递归解析器是"递归查询"(你只管要最终答案,过程我全包);递归解析器 → 根/TLD/权威是"迭代查询"(每一级只回答"我不知道,但你该去问谁",解析器拿着线索一级级自己问下去)。这个分工是 DNS 流程的核心。

三、一次完整解析:递归 + 迭代走一遍

假设你的浏览器要解析 www.example.com,且各级缓存都没命中。完整流程如下:

sequenceDiagram participant C as 客户端 participant R as 递归解析器 participant Root as 根服务器 participant TLD as .com 服务器 participant Auth as example.com 权威 C->>R: 查询 www.example.com (递归查询) R->>Root: www.example.com 的地址? (迭代) Root-->>R: 我不知道,去问 .com 的TLD服务器 R->>TLD: www.example.com 的地址? (迭代) TLD-->>R: 我不知道,去问 example.com 的权威 R->>Auth: www.example.com 的地址? (迭代) Auth-->>R: A 记录 = 93.184.216.34 R-->>C: 答案是 93.184.216.34 (并缓存)

逐步看:

  1. 客户端问递归解析器:“www.example.com 是什么 IP?” 这是一次递归请求——客户端把活全交给解析器,只等最终答案。
  2. 解析器问根服务器:根不知道具体 IP,但回答".com 由这些 TLD 服务器管,去问它们"。这是迭代——只给线索。
  3. 解析器问 .com 的 TLD 服务器:TLD 也不知道具体 IP,但回答"example.com 的权威服务器在这里"。
  4. 解析器问 example.com 的权威服务器:权威服务器手握记录,返回 A 记录 = 93.184.216.34
  5. 解析器把答案返回给客户端,同时按 TTL 缓存这条记录,供后续查询直接命中。

看清这条链,就理解了 DNS 的精髓:客户端只发一次递归请求,繁琐的逐级迭代由递归解析器代劳,且每一级结果都会被缓存。 正因为有缓存,绝大多数查询根本走不到根服务器——否则全球查询压垮根早就发生了。

四、缓存与 TTL:DNS 真正的性能命脉

如果每次解析都从根走一遍,延迟和压力都不可接受。所以缓存无处不在,分布在多个层级:

  • 浏览器自己的 DNS 缓存;
  • 操作系统的缓存(及 hosts 文件,优先级最高);
  • 递归解析器的缓存(命中率最高、最关键的一层)。

每条 DNS 记录都带一个 TTL(Time To Live),规定它能被缓存多久。TTL 一到,缓存失效,下次查询要重新解析。

TTL 的设置是个典型权衡:

  • TTL 长:缓存命中率高、查询压力小、解析快,但记录变更后生效慢——改了 IP,老客户端可能几小时还在用旧地址。
  • TTL 短:变更几乎立刻全网生效,切换灵活,但查询频次高、解析器和权威服务器压力大。

真实世界里的发布、切流、容灾、故障迁移,全都要和 TTL 打交道。要做快速切换的服务(比如准备故障转移的域名)会预先把 TTL 调短;稳定不变的记录则用长 TTL 省查询。TTL 本质是在"传播速度"和"查询成本"之间定刻度。

五、记录类型:DNS 不只存 IP

DNS 本质是一套分布式键值查询系统,域名是 key,而 value 可以是多种记录类型,不止 IP:

  • A:域名 → IPv4 地址(最常用)。
  • AAAA:域名 → IPv6 地址。
  • CNAME:别名,把一个域名指向另一个域名(如 www.example.com → example.com)。CDN 调度大量依赖它。
  • NS:指明这个域由哪些权威服务器管(上面流程里 TLD 返回的就是 NS 记录)。
  • MX:邮件交换记录,指明收这个域邮件的服务器。
  • TXT:任意文本,常用于域名所有权验证(如 SSL 证书申请、SPF 反垃圾邮件)。

理解 CNAME 尤其重要——它是 CDN 工作的基础(下一篇会用到):你把 www.yoursite.com 用 CNAME 指向 CDN 厂商的域名,CDN 再用智能解析把它指到最近的边缘节点 IP。

六、看懂机制后,再问:为什么这样设计

为什么要分层分布式,而不是一个大字典? 规模和管理。全球域名数以十亿计、每秒查询天文数字,单点必然崩溃。分层让每一级只管自己那一层(根只管 TLD、TLD 只管二级域),管理权也随之下放——example.com 的记录由你自己改,不必惊动根或 TLD。分层既分摊了查询压力,也分散了管理职责。

为什么要分递归和迭代两种查询? 让客户端保持简单。客户端只想要最终答案,不该懂逐级追问的复杂逻辑,所以发递归请求、把活外包给解析器。而解析器做迭代,是因为根/TLD 服务器只愿意"给线索"而不愿"包办到底"——否则它们要承担的递归压力会爆炸。这是一种职责和负载的合理分配。

为什么缓存如此核心? 因为 DNS 查询有极强的局部性(热门域名被反复查),且记录变化不频繁。缓存 + TTL 用很小的"陈旧风险"换来了巨大的性能和压力收益,让分布式系统真正可用。

七、为什么 DNS 故障总像"随机抽风"

这是 DNS 最让工程师头疼的特性,而它正是上述机制的副作用:

因为缓存散落在多个层级、TTL 不同、各地递归解析器策略各异,不同用户、不同运营商、不同时间点看到的解析结果可能不一致:有人已拿到新记录,有人还命中旧缓存;某个运营商的解析器抽风返回了异常结果,别的却正常。于是用户描述成"我这能打开,他那打不开"“有时好有时坏”。

DNS 故障的诡异,本质来自它的分布式缓存:它不像单点宕机那样"非黑即白",而是一种会随缓存过期、随地域、随解析器漂移的现象。排查时绝不能只 nslookup 一次看一个结果就下结论。

八、和工程实践 / SRE 的联系

  • 排查别只看一个结果:要分层查——dig +trace 看完整迭代路径,对比本地缓存、不同递归解析器(dig @8.8.8.8 vs dig @114.114.114.114)、权威服务器的直接响应,看是哪一级出了问题或缓存不一致。
  • 发布与切流要算好 TTL:上线前若计划切 IP,提前几天把 TTL 调短,切换时才能快速全网生效;切完再调回长 TTL。不懂 TTL,切流后会困惑"为什么还有一半流量打到老机器"。
  • CDN 调度的入口:CDN 靠 DNS(CNAME + 智能解析)把用户导向最近节点。理解 DNS,才看得懂 CDN 调度链路(下一篇详谈)。
  • DNS 也影响证书与回源:证书校验、回源链路、服务发现很多都依赖 DNS。一次解析异常可能表现成"证书错误""回源失败"等看似无关的现象。
  • 公共 DNS 与解析污染:某些网络环境存在 DNS 劫持/污染,导致解析到错误 IP。改用可信公共 DNS 或 DoH/DoT(加密 DNS)是常见应对。

学习这一部分最容易踩的坑

1. 分不清递归查询和迭代查询

客户端→递归解析器是递归(要最终答案);解析器→根/TLD/权威是迭代(逐级要线索)。混淆这两者,就讲不清那次查询到底是谁在逐级追问。

2. 以为每次访问都从根服务器查起

绝大多数查询命中缓存,根本到不了根。正因为多级缓存的存在,根服务器才扛得住全球流量。

3. 忽视 TTL 导致的传播延迟

改了 DNS 记录不会立刻全网生效,老缓存要等 TTL 过期。不懂这点,发布切流时会反复踩"为什么改了还不生效"的坑。

4. 把 DNS 故障当成单点硬故障

DNS 问题常表现为"部分用户、部分时段"的漂移现象,源于分布式缓存不一致。当成单点宕机去查,方向就错了。

总结

这一篇我们完整走了一遍 DNS 解析流程,坚持先机制后设计:

  • 域名从右到左分层(根 → TLD → 二级域 → 主机),层级结构是逐级查询的骨架;
  • 客户端→递归解析器是递归查询(要最终答案),解析器→根/TLD/权威是迭代查询(逐级要线索);
  • 一次完整解析经根、TLD、权威三级,最终由权威服务器给出记录,解析器代劳并缓存;
  • 多层缓存 + TTL 是 DNS 的性能命脉,TTL 在"变更传播速度"和"查询成本"间权衡;
  • DNS 是分布式键值系统,记录类型不止 A,CNAME 是 CDN 调度的基础;
  • 分层分布式分摊了查询压力与管理职责,缓存的副作用是故障表现为"随机漂移"。

看懂 DNS,你会发现"输入域名"这个看似简单的动作,其实是整个互联网访问链路真正的起点。下一篇我们顺着 DNS 调度,进入 CDN 与反向代理——内容是怎么被就近分发、请求又是怎么被层层转发到后端的。

参考资源