在浏览器敲下网址的那一秒,到底发生了什么?——DNS 解析的完整旅程
408 · 计算机网络(25 分)· 应用层。DNS 的层次结构、递归查询与迭代查询、缓存与 TTL、以及"为什么 DNS 用 UDP"——这是应用层最常考的选择题来源之一。
一次"从敲回车到网页出现"的 0.3 秒
你在地址栏敲下www.example.com,回车,页面眨眼就出来了。就这一眨眼之间,你的电脑其实完成了一场横跨全球的"问路"接力——因为网络世界里,机器只认 IP 地址,不认域名。www.example.com这个名字,必须先被翻译成一个 IP(比如93.184.216.34),后面的 HTTP 请求才有处可去。
这台"把名字翻译成 IP"的全球分布式系统,就是DNS(Domain Name System,域名系统)。它常被称作"互联网的电话簿",但真实运作远比电话簿精妙——分布式、分层次、带缓存、有容灾。这篇文章就把那一秒里发生的事,从头到尾讲清楚。
为什么需要 DNS:一个"记不住"和"改不了"的矛盾
最初,主机名和 IP 的对应关系就存在一个文件/etc/hosts里,每台机器一份。可互联网一膨胀,两个问题立刻暴露:
- 名字太多记不住:
93.184.216.34这串数字,没人愿意背;www.example.com却一目了然。 - IP 一改全得跟着改:服务器换了 IP,全世界所有机器的 hosts 文件都要同步更新——这不现实。
DNS 的解法是:域名分层次,解析分布式,再靠缓存扛住海量查询。
域名的层次:从右往左读
域名是按层次组织的,从右到左逐级细化:
www ⏟ 三级 . example ⏟ 二级 . com ⏟ 顶级 TLD . (root) ⏟ 根,通常省略 \underbrace{\text{www}}_{三级}\ .\ \underbrace{\text{example}}_{二级}\ .\ \underbrace{\text{com}}_{顶级\ \text{TLD}}\ .\ \underbrace{\text{(root)}}_{根,通常省略}三级www.二级example.顶级TLDcom.根,通常省略(root)
最右边有一个根域(写作.,平时省略)。完整的www.example.com.末尾那个点,就是根。负责解析的服务器也对应分成四级:
根域名服务器 ──▶ 顶级域(TLD)服务器(.com) ──▶ 权威域名服务器(example.com) ──▶ 返回 IP根服务器全球只有十几组(任播部署到上千个节点),它不直接知道www.example.com的 IP,只告诉你".com的服务器在哪";.com服务器又告诉你"example.com的权威服务器在哪";最终由权威服务器给出答案。每一级只负责自己的那一段,这就是分布式。
递归查询 vs 迭代查询:谁去"跑腿"的区别
DNS 查询有两条路,区别在于谁来跑腿:
递归查询(recursive):你把问题丢给本地 DNS 服务器(运营商或公共 DNS 如8.8.8.8),它替你一级级问到底,最后只把最终答案返回给你。你只发了一次查询:
客户端查询次数 = 1 \text{客户端查询次数} = 1客户端查询次数=1
迭代查询(iterative):本地 DNS 服务器不替你跑全程,而是每问一级,就把"下一级服务器地址"告诉你,让你(或它)自己再问下一级。典型流程是:客户端问本地 DNS,本地 DNS迭代地问根 → 问 TLD → 问权威,把沿途的"线索"一步步拿回来。
考试常考:主机向本地 DNS 服务器发出的,通常是递归查询;而本地 DNS 服务器向根、TLD、权威服务器发出的,通常是迭代查询。别搞反了方向。
一次完整旅程(以 www.example.com 为例)
1. 你在浏览器输入 www.example.com 2. 查浏览器缓存 → 没有 → 查操作系统缓存(hosts) → 没有 3. 向本地 DNS 服务器发【递归查询】 4. 本地 DNS 服务器向【根服务器】发迭代查询:"www.example.com 在哪?" 根答:"我不知道,但 .com 的服务器在 192.x.x.x" 5. 本地 DNS 向【.com TLD 服务器】问 TLD 答:"我不知道,但 example.com 的权威服务器在 93.x.x.x" 6. 本地 DNS 向【权威服务器】问 权威答:"www.example.com 的 IP 是 93.184.216.34" 7. 本地 DNS 把答案缓存起来,返回给你的电脑 8. 你的浏览器拿到 IP,发起 TCP 连接 → HTTP 请求 → 页面出现注意第 2 步和第 7 步的两级缓存——它才是 DNS 能扛住全球海量查询的关键。
缓存与 TTL:DNS 为什么这么快
每一级都缓存查询结果,下次直接命中,不用再跑到根服务器。但缓存不能永久——域名对应关系会变,所以每条记录都带一个TTL(Time To Live,生存时间),单位秒。缓存过期就作废,重新查询。
TTL 是一把双刃剑:设短了,变更传播快但查询多;设长了,缓存命中高但"改 IP 要等很久才生效"。运维在给域名换 IP 前,往往会先把 TTL 调短,让旧缓存尽快过期。
为什么 DNS 用 UDP:快,但也有例外
DNS 默认走UDP 53 端口,而不是 TCP。原因很务实:
- 查询/响应都很短,通常一个包就能装下,不需要 TCP 的三次握手;
- 无连接、开销小,扛得住海量并发查询;
- 丢了就重发——DNS 应用层自己处理重试。
但有两个例外会用 TCP 53:响应超过 512 字节(DNS 报文传统上限,需要 TCP 传输大数据,如 DNSSEC 记录),以及区域传送(zone transfer)——主从 DNS 服务器之间同步整个区域数据,必须可靠传输。
收束
回到那一秒:你敲下www.example.com,浏览器查缓存、问本地 DNS,本地 DNS 又迭代地跑了一趟"根 → .com → 权威"的接力,把名字翻译成 IP,最后缓存下来。这一套分层 + 分布式 + 缓存 + 递归/迭代分工的设计,让全球几十亿台设备都能在毫秒级完成"问路",而核心服务器却只有那么几组。
一句话带走:DNS 的本质,是一个靠"层次划分"和"层层缓存"支撑起来的、全球性的分布式查表系统——名字好记给人看,IP 给机器用,DNS 就是中间那座桥。
DNS 是计算机网络应用层的核心协议,常与 HTTP、TCP 一起综合考查,B站【408实验室】的《数据结构》配套考研课程里有体系化的网络专题,适合把五层模型串起来刷。