【从0开始学习计算机网络】|DNS 解析:从你在浏览器敲下回车到页面加载,中间发生了什么
🌈个人主页:一条泥憨鱼(欢迎各位大佬莅临)

🎬精选专栏传送门:
❄️《数据结构》 ❄️《AI与Agent那些事》
❄️《从0开始学计算机网络》 ❄️《后端开发》

前言:
泥憨鱼在上周值班的时候,一个同事急匆匆跑过来说"网站挂了"。泥憨鱼打开浏览器试了一下,确实打不开,但奇怪的是——隔壁工位的人说能打开。再一看,他自己电脑上 curl 一个内网 IP 完全正常。
折腾了十分钟,最后发现是他笔记本的 DNS 配置被某个 VPN 客户端改掉了,解析到了一个错误的地址。
这种场景你肯定不陌生。DNS 平时安安静静地躺在系统角落里,没人注意它,但一旦出问题,表现极其诡异——有时候是"时好时坏",有时候是"换个网络就好了",有时候是"手机能开电脑不能开"。排查起来也特别烦,因为问题不在你的服务器上,也不在你的代码里,而是在一条你完全看不见的链路上。
这篇文章,把 DNS 解析的完整链路讲清楚。从你在浏览器地址栏敲下回车开始,到页面真正加载出来,中间到底发生了多少次请求、经过了哪些节点、哪些环节最容易出幺蛾子。
先从直觉理解 DNS 在干什么
打个比方。你手机通讯录里存的都是名字:"老王"、"陈总"、"修空调的张师傅"。真要打电话的时候,系统得先把名字翻译成对应的电话号码。DNS 干的就是这活儿——把 `www.example.com` 这样的域名翻译成 `93.184.216.34` 这样的 IP 地址。
为什么不能直接用 IP?你试试记住你常访问的二十个网站的 IP,还得保证它们哪天换了 IP 你能第一时间知道。域名系统存在的意义就是让人用好记的名字,让机器用好找的地址,两边各取所需。
但这里有个细节值得注意:DNS 不是一个"中央数据库",而是一个分布式的、分层管理的系统。这个设计不是拍脑袋想出来的——如果全世界只有一个 DNS 服务器,它挂了全世界都断网,而且流量也扛不住。所以 DNS 的设计是:数据分散存储在很多很多台服务器上,每台只管自己那一亩三分地。
还有一个经常被忽略的"本地小本本":hosts 文件。在 Linux/macOS 上是 `/etc/hosts`,Windows 上是 `C:\Windows\System32\drivers\etc\hosts`。这个文件的优先级比 DNS 服务器还高,系统会先查它,查不到才走 DNS 查询。这也是为什么有时候你改了 DNS 配置但解析结果没变——先看看 hosts 文件是不是被改过。

递归查询 vs 迭代查询,搞清楚谁在替我们跑腿
现在进入正题。你在浏览器输入 `www.example.com` 回车,浏览器第一个动作不是发 HTTP 请求,而是问操作系统:"这个域名的 IP 是多少?" 操作系统查了一下自己的缓存,没有,于是把这个问题抛给了系统配置的 DNS 服务器——通常是你的路由器指向的 ISP 的 DNS,也可能是你手动设置的 8.8.8.8 或 114.114.114.114。
这台被问到的服务器,就是递归解析器。它的职责是"替你把问题查到底,然后告诉你答案"。它自己可能也不知道答案,但它知道该去问谁。
接下来是迭代查询。递归解析器先去问根域名服务器(全球一共 13 组,分布在世界各地):"www.example.com 的 IP 是什么?" 根服务器说:"我不知道,但 .com 顶级域的服务器地址是这些,你去问它。" 递归器再去问 .com 的顶级域服务器,对方说:"example.com 的权威服务器是这几台,去问它们。" 最后递归器找到 example.com 的权威服务器,拿到 `www` 这条记录的 IP,然后把这个结果原路返回给你的电脑。
整个链路大概是这样
你的浏览器
↓ (递归查询)
本地 DNS 解析器(比如 8.8.8.8)
↓ (迭代查询)
根域名服务器("我不知道,去问 .com 的服务器")
↓
.com 顶级域服务器("我不知道,去问 example.com 的权威服务器")
↓
example.com 权威服务器("www 的 IP 是 93.184.216.34")
↓
原路返回 → 你的浏览器
```
注意一个关键点:递归和迭代的区别。
- 递归:你只问一次,剩下的跑腿全由对方负责,对方必须给你最终答案。
- 迭代:每次问一个节点,对方只告诉你"下一步该问谁",你自己一步步往前走。
实际场景中,你的电脑和本地 DNS 之间是递归关系,而本地 DNS 和根/顶级域/权威服务器之间是迭代关系。这也是为什么你配置一个 DNS 服务器地址就够了,剩下的事情全由它代劳。
这里还有个容易混淆的概念:权威服务器。它才是某个域名的"最终话事人",域名解析的最终答案以它为准。如果你自己买了个域名,托管在阿里云或 Cloudflare,那它们的 DNS 服务器就是你这个域名的权威服务器。
缓存机制:为什么第二次访问快那么多
你肯定注意到过:第一次访问一个新网站有点慢,第二次就快很多。除了浏览器缓存了静态资源,DNS 缓存也功不可没。
DNS 解析的完整链路走一遍,正常情况要几十毫秒,如果某些环节网络不好,可能要上百毫秒。但加了缓存之后,第二次访问可能连 1 毫秒都不用。
缓存放了好几层,从近到远:
1. 浏览器缓存:Chrome 自带 DNS 缓存,`chrome://net-internals/#dns` 可以查看。
2. 操作系统缓存:浏览器查不到就查系统的,`ipconfig /displaydns`(Windows)或 `sudo killall -HUP mDNSResponder`(macOS 清缓存)可以操作。
3. 本地 DNS 解析器缓存:你配置的 8.8.8.8 或路由器上的 DNS 缓存。
4. ISP 缓存:运营商级别的缓存,一般用户感知不到。
每一层缓存都有一个关键参数:TTL(Time To Live)。每条 DNS 记录都带一个 TTL,告诉接收方"这条记录你可以缓存多久"。单位是秒,常见的值是 300(5 分钟)到 86400(24 小时)。

TTL 这个参数,运维的时候特别容易踩坑。
TTL 设太短——比如 30 秒——好处是域名指向变更后能快速生效,坏处是每个请求都要走完整链路,DNS 查询压力大,首次访问延迟高。
TTL 设太长——比如 7 天——好处是查询快、压力小,坏处是你要换服务器 IP 的时候,全世界各地的缓存要等整整 7 天才能全部刷新。这期间一部分用户访问旧 IP,一部分访问新 IP,体验极其分裂。
一个真实案例:某团队把 TTL 设成了 604800(7 天),后来要切流到新服务器,改完 DNS 记录后等了整整一周才敢把旧服务器下线。那周他们每天都被用户投诉"网站一会儿能开一会儿不能开"。
那些年我们踩过的 DNS 坑
DNS 的问题不像代码 bug 那样有 stack trace 可查,经常是"薛定谔的故障"——你排查的时候它好了,你不管它的时候它又坏了。分享几个常见的坑。
DNS 污染。最常见于跨境访问场景。你的 DNS 请求在传输过程中被中间设备篡改,返回了一个错误的 IP,通常是指向一个广告页或者警告页。表现是:你在国内访问某些国外网站,偶尔会跳到一个"根据相关法律法规"的页面。这不是网站挂了,是你的 DNS 解析结果被改了。
DNS 劫持。 比污染更隐蔽。攻击者控制了你的 DNS 解析结果,把 `bank.com` 解析到他们伪造的钓鱼网站。你看到地址栏是对的,但实际访问的 IP 是假的。防范手段是启用 DNSSEC(DNS 安全扩展),以及尽量用 HTTPS 访问网站——就算 DNS 被劫持,HTTPS 的证书校验也能拦一道。
缓存导致的故障。 我前面说的 TTL 案例就是典型。还有一种情况:你改了 DNS 记录,但本地电脑的 DNS 缓存还在生效,导致你"明明改了却看不到效果"。排查的时候第一件事就是 `ipconfig /flushdns`(Windows)或者 `sudo dscacheutil -flushcache`(macOS)。
TTL 和故障转移的关系。 如果你的服务挂了,你想把流量切到备用服务器,这时候 DNS 的 TTL 决定了你的切换速度。所以正规的运维流程是:提前把 TTL 调低(比如 60 秒),等缓存都刷新了,再改 DNS 记录指向新服务器,确认稳定后再把 TTL 调回来。
排查 DNS 问题,我建议你记住这几个命令:
# 查看完整解析链路,能看到每一步花了多少时间
dig +trace www.example.com
# 只看解析结果和 TTL
dig www.example.com
# 指定 DNS 服务器查询,绕过本地缓存
dig @8.8.8.8 www.example.com
# Windows 上清 DNS 缓存
ipconfig /flushdns
# 查看系统 DNS 配置
cat /etc/resolv.conf # Linux
ipconfig /all # Windows
```
这里多说一句:`ping` 不能用来排查 DNS。因为 ping 用的是 ICMP 协议,有些服务器禁 ping,而且 ping 的报错信息太模糊,分不清是 DNS 问题还是网络问题。要看 DNS 就用 `dig`,它给出的信息干净利落。

最后
回头看整个 DNS 解析链路,其实就四步:查缓存、问递归器、递归器迭代问根/顶级/权威服务器、拿到答案返回。真正的网络请求只有几十毫秒,但里面涉及了分布式系统、缓存一致性、安全防护这些大话题。
建议你动手做个小实验:打开终端,跑一下 `dig +trace www.baidu.com`,你会看到真实的根服务器、顶级域服务器和权威服务器列表,每一跳的耗时都清清楚楚。看完你就明白,这篇文章讲的不是纸上谈兵,而是你每天上网都在经历的真实路径。
DNS 是那种"不出问题你永远想不起它"的基础设施,但一旦出问题,它的排查难度远超你的想象。希望这篇文章能帮你省下几个小时的排查时间。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)