跳转到内容

关于 DNS 解析的那些事儿,可能比你想象的要复杂!

前端面试经常被问的题目:从浏览器输入一个域名,到最后的页面呈现,中间到底经历了什么?

本篇文章将详细讲解“域名解析”部分的知识,彻底弄清楚解析的过程与相关概念!

从“域名到渲染”的全过程

先快速过一遍:

第 1 步:域名解析 → 拿到 IP 地址

  • 检查浏览器缓存
  • 检查操作系统缓存
  • 向本地域名服务器查询(电信、联通、8.8.8.8、1.1.1.1 等)
  • 递归查询

第 2 步:建立连接 → 下载 HTML 文档

  • 建立 TCP 连接(3 次握手)
  • 如果是 HTTPS 则继续 TLS 握手
  • 发送 HTTP 请求
  • 服务器返回 HTML 文档

第 3 步:HTML 解析 → 呈现 UI 效果

  • 构建 DOM 树
  • 下载 CSS 并解析为 CSSOM
  • 下载 JS 并执行(开启asyncdefer不会阻塞)
  • 异步加载图片等资源
  • 生成渲染树(可见节点:Render Tree = DOM + CSSOM)
  • 布局(计算位置、尺寸、边距等,也就是回流
  • 绘制(颜色、文本、边框等视觉呈现,重绘就在这一步)
  • 合成(普通层、GPU 层、transform layer 等),显示到屏幕

"

📌 参考文章:

总共 3 步,每个步骤只需记住一些关键字,基本上就可以拿来应付面试了。

接下来,进入文章的重点内容。

DNS 解析原理

本地 DNS 缓存

优先级从高到底依次是:

  • hosts 文件
  • 浏览器缓存
  • 系统缓存
  • 路由器缓存
  • 运营商缓存

hosts 文件是开发人员使用的最多的,如果想在本地指定一个域名到 IP 地址,通常都会修改本地 hosts 文件。

浏览器 DNS 缓存通常存在于内存中,有效期非常短。

系统缓存我们可以使用以下方式查看:

bash
# windows
ipconfig /flushdns

既然有这么多级缓存,如果域名解析记录被修改后,本地缓存如何知道记录变了呢?

TTL 缓存有效期

TTL(Time To Live)就是 DNS 记录的“有效期”,它就是用来告诉各级缓存:这个域名的解析结果最多能缓存多久

各级缓存通常也会严格遵守这一约定。

这个 TTL 时间我们可以在“配置解析记录”时指定:

指定 TTL

如果你的域名不经常改变,可以把时间设置得更长一点,避免频繁触发递归解析 DNS,提高访问速度。

递归查询

如果你是第一次访问一个域名,或者缓存过期,就会走递归查询(Recursive Query)

所谓递归查询就是:递归解析服务器会自动帮你层层“向上查询”,直到拿到最终的 IP 地址再返回给你

那我们看看具体是怎么个向上查询法:

  1. 查询根域名服务器
  • 递归解析器询问根域名服务器:告诉我codingmo.com的 IP 是多少?
  • 根服务器不直接回答,而是返回.com的顶级域名服务器地址:你自己问它吧。
  1. 查询顶级域名服务器
  • 继续询问:告诉我codingmo.com的 IP 是多少?
  • 也不直接回答,而是返回此域名的权威域名服务器的地址:你自己问它吧。
  1. 查询权威域名服务器
  • 继续询问:告诉我codingmo.com的 IP 是多少?
  • 返回具体的 IP 地址。

我们可以看到,每一次查询,范围都缩小了一圈,最终返回 IP 地址的是👉 权威域名服务器

"

📌 简单捋一下这几个概念:

  • **递归解析服务器:**帮你完成 IP 查询的服务器。(运营商、8.8.8.8 等)
  • **根域名服务器:**管理了.com.net等所有顶级域名对应的服务器。
  • **顶级域名服务器:**如.com,只负责.com下所有域名对应的权威域名服务器。
  • **权威域名服务器:**管理具体的域名,你配置的 DNS 解析记录就是它在管理。

权威域名服务器

因此,权威域名服务器才是真正记录你域名的地方,而且也必须是“被顶级域名所认可”的服务器。

如果你从阿里云、腾讯云注册了一个域名,通常默认会使用他们给你提供的权威域名服务器,所以你配置 DNS 解析记录时,需要去阿里云或腾讯云平台进行处理。

那能否更改权威域名服务器呢?

自然是可以的。

你不需要迁移域名所属服务商,只需要修改对应的 NS 服务器就行了。

修改权威域名服务器

如此一来,后续配置 DNS 解析记录,就需要去你指定的服务商去处理了。

👉 查看权威域名服务器

任何一个域名,你都可以查看它的权威域名服务器:

bash
nslookup -type=ns github.com

查询权威域名服务器

👉 查询 IP 地址

你也可以查看任何一个域名的解析记录,如:

bash
nslookup github.com

查询 IP 地址

可以看到,github.com对应的IP20.205.243.166

👉 直接使用权威服务器查询 IP

在拿到权威服务器后,不需要递归解析器也可以直接查询:

bash
nslookup github.com dns4.p08.nsone.net

查询 IP 地址

此时,你直接访问权威服务器查询域名的 IP 地址,所以结果中不再显示“Non-authoritative answer”。因为你是通过权威服务器直接查询的,是绝对安全可信任的!

👉 指定第三方解析器查询

bash
nslookup github.com 1.1.1.1

第三方解析器查询

细心的同学可能发现了,使用1.1.1.1查询github.com的 IP 地址与上面的不一样!这是为什么呢?

这其实是很正常的。因为它们在全球分布了很多台服务器,不同的位置、不同的解析器查询到的 IP 地址就有可能不一样。

DNS 相关问答

❓ 如果一个域名配置的是 CNAME 记录,又是怎样解析的呢?

我们先直接用命令查看:

bash
nslookup unoapi.codingmo.com

CNAME 记录

实际上查询到了 3 条记录:第 1 条是你配置的 CNAME 记录,后面两条是自动查询出来的IP地址。

其实我们也不难判断,递归解析器发现查到的结果不是 IP 地址,它会自动再次走递归查询的流程,询问 CNAME 域名对应的 IP 地址是多少,直到最终返回的是 IP 地址。

❓ 那如果 CNAME 记录相互循环引用了,会怎样呢?

比如:域名 A 的 CNAME 指向域名 B,域名 B 的 CNAME 又指向域名 A。

循环引用

然后我们来测试一下:

查询超时

查询过程会持续几秒钟,然后会提示查询超时,也不会响应任何记录。

❓ 操作系统中配置的 DNS 有什么用?

系统DNS

这就是递归解析服务器,它是你配置并信任的服务器,它可以一键帮你查询域名对应的 IP 地址。

通常不需要我们手动配置,路由器会自动下发 DNS 到我们的终端设备中,路由器中的 DNS 通常就是由运营商提供的。

路由器DNS

所以,我们也经常会看到一些人配置成:

  • 8.8.8.8:Google 提供的递归解析服务器
  • 1.1.1.1:Cloudflare 提供的解析器

使用这些比较权威的第三方公共 DNS 解析器,通常会更加安全。

总结

文章比较长,总结一下比较重要的点:

  • 域名解析会优先使用本地缓存的 IP 地址
  • 其次才会通过“递归解析器”来查询 IP 地址

关于递归解析,涉及两个重要概念:

  • 权威域名服务器:直接记录了你域名的解析记录
  • 递归解析服务器:自动帮你查询域名的 IP 地址

递归解析过程:

"

递归解析器 → 根域名服务器 → 顶级域名服务器 → 权威域名服务器 → IP 地址


还有任何疑问请在评论区讨论~