DNS:把域名翻译成 IP 的层级查询机制
目录
DNS是什么
DNS(Domain Name System,域名系统)是一套将域名翻译成 IP 地址的协议。你在浏览器输入 www.example.com,浏览器拿到的是域名,但真正要建立 TCP 连接,需要的是 93.184.216.34 这样的 IP 地址。DNS 干的就是这个翻译工作。
但它不只是一个简单的"查表"服务。DNS 是一个分布式的、层级化的数据库系统。全球的域名信息不存在一台服务器上,而是按层级分散在不同的服务器中,每一级只负责自己管辖范围内的解析。
为什么需要 DNS
最直接的原因:人记不住 IP 地址,但能记住域名。
早期互联网规模很小,用一个 hosts 文件就能解决问题。每台机器上维护一个 域名 → IP 的映射表,查域名就在本地文件里找。
# /etc/hosts
127.0.0.1 localhost
93.184.216.34 www.example.com
但这种方式撑不住互联网的增长。全球有数亿个域名,每天还有大量新增、变更、删除。让每台电脑都维护一份完整的映射表不现实。就算能同步,文件体积和更新频率也是问题。
DNS 的解决方案是分布式存储。全球的域名信息按层级切分,分布在不同的服务器上。每台服务器只负责一小部分,查询时逐级往下找。这样既解决了存储容量问题,也让管理变得可控------某个域名的变更只需要通知对应的权威服务器,不需要全球同步。
四种域名服务器
DNS 的层级体系里有四种角色,各司其职:

根域名服务器(Root Name Server)
全球共 13 组根域名服务器(逻辑编号 A 到 M),使用任播(Anycast)技术,实际物理节点超过 1000 个,遍布全球。根服务器不直接解析域名,它的作用是告诉你"该去哪问"。比如你查 www.example.com,根服务器不认识这个域名,但它知道 .com 归谁管,把请求指向 .com 的顶级域名服务器。
顶级域名服务器(TLD Name Server)
管理顶级域名(如 .com、.org、.cn、.net)的服务器。它知道某个二级域名(如 example.com)的权威服务器在哪,但不直接返回最终的 IP 地址。
权威域名服务器(Authoritative Name Server)
域名持有者自己配置的服务器(或托管在 DNS 服务商),里面存着域名的最终解析记录。比如 www.example.com 的 A 记录指向 93.184.216.34,这条记录就存在权威服务器上。查询到了这一层,就能拿到最终的 IP。
本地 DNS 服务器(Local DNS Server / Recursive Resolver)
也叫递归解析器,通常由你的运营商(ISP)或公共 DNS 服务商(如 8.8.8.8、114.114.114.114)提供。它是客户端和整个 DNS 层级体系之间的中间人。客户端只需要把查询发给它,它负责逐级去问,最终把结果带回来。
一次完整的解析流程
以你在浏览器输入 www.example.com 为例,走一遍完整的解析过程。
第一步:浏览器缓存
浏览器会先查自己的 DNS 缓存。如果之前访问过这个域名且缓存没过期,直接返回 IP,流程结束。
第二步:操作系统缓存
浏览器没命中,操作系统会查自己的 DNS 缓存(包括 hosts 文件)。如果命中,直接返回。
第三步:请求本地 DNS 服务器
操作系统缓存也没有,系统会把查询发给配置的本地 DNS 服务器(通常是运营商自动分配的,或者你手动设置的 8.8.8.8 等)。
第四步:本地 DNS 服务器开始迭代查询
这是整个流程的核心。本地 DNS 服务器没有 www.example.com 的缓存,它需要从根开始逐级查询:

第五步:建立连接
浏览器拿到 IP 地址,开始 TCP 三次握手,建立连接,发送 HTTP 请求。
整个过程从浏览器到本地 DNS 是一次查询,从本地 DNS 到各级服务器是多次迭代查询。对客户端来说,它只发了一次请求,等了一次响应。中间的复杂过程全由本地 DNS 服务器代劳。
递归查询vs迭代查询
DNS 查询有两种模式,经常被混为一谈,但它们的含义完全不同。
递归查询
客户端把查询"委托"给本地 DNS 服务器,要求它必须返回最终结果(IP 地址或查询失败)。客户端不需要关心中间过程。
迭代查询
本地 DNS 服务器向根、TLD、权威服务器发起的查询。每一级服务器只返回它知道的下一级服务器地址,不会替你继续往下问。本地 DNS 服务器需要自己一层层追下去。
实际的 DNS 解析中,两种模式同时存在:
| 查询路径 | 模式 | 原因 |
|---|---|---|
| 客户端 → 本地 DNS | 递归 | 客户端只发一次请求,等最终结果 |
| 本地 DNS → 根/TLD/权威 | 迭代 | 每一级只返回下一步该问谁 |

为什么不让根服务器做递归查询?因为根服务器要服务全球的 DNS 请求,如果每个查询都要它从头追到尾,负载根本扛不住。迭代查询让每一级服务器只做一件事------返回下一级的地址,把真正的追踪工作交给了本地 DNS 服务器。
DNS 缓存
DNS 查询要经过多层服务器,如果每次都从根开始找,效率太低。缓存机制让重复查询可以直接命中,不用再走完整的解析链路。
浏览器缓存
Chrome 可以在地址栏输入 chrome://net-internals/#dns 查看浏览器的 DNS 缓存。浏览器缓存的 TTL 通常较短,一般几分钟到几十分钟。
操作系统缓存
操作系统层面也有 DNS 缓存。Windows 下可以用 ipconfig /displaydns 查看。操作系统缓存会检查 hosts 文件,也会缓存之前查询过的结果。
本地 DNS 服务器缓存
这是影响范围最大的一层缓存。本地 DNS 服务器服务的是整个区域的用户,如果某个热门域名(如 www.baidu.com)已经有人查过了,后续所有用户的查询都能直接命中缓存。
每条 DNS 记录都有一个 TTL(Time To Live)字段,表示这条记录可以被缓存多久。比如一条 A 记录的 TTL 是 3600 秒,意味着缓存这条记录的服务器在一小时内不会再向上查询,直接返回缓存值。
TTL 的影响:
TTL = 300(5分钟) → 记录变更后最多 5 分钟全网生效,适合频繁变更的场景
TTL = 86400(24小时)→ 记录变更后最长 24 小时才全网生效,但查询效率更高
TTL 的设置是一个权衡。设得太短,缓存命中率低,查询延迟高;设得太长,域名记录变更后生效慢。迁移服务器时,通常的做法是提前把 TTL 调低,等旧缓存过期后再修改 IP 记录,最后再把 TTL 调回去。
总结
DNS 把域名到 IP 的翻译工作拆成了层级化的分布式查询:客户端只管问本地 DNS 服务器,本地 DNS 服务器逐级向下迭代,最终从权威服务器拿到结果。缓存机制让大部分查询不需要走完整链路。
但 DNS 协议本身有不少局限。查询过程是明文传输的,中间人可以轻易看到你在访问什么域名,也可以篡改响应把你的流量劫持到恶意服务器。DNS 劫持、DNS 污染这些问题在实际网络环境中并不少见。为了解决这些问题,DoH(DNS over HTTPS)和 DoT(DNS over TLS)被提出,它们在传输层对 DNS 查询做了加密,防止中间人窥探和篡改。但这也带来了新的争议:加密后的 DNS 流量绕过了运营商的传统监控手段,给网络管理和安全审计带来了新的挑战。