DNS面试也会问,赶紧来看看

3,067 阅读20分钟

本文正在参与 “网络协议必知必会”征文活动

写在前面的话

最近时间面试被问到不少 DNS 相关的问题,正好看见掘金有征文活动。于是整理出这篇文章。

虽然文章滚动条很小,但是内容充实,各位看官可以静下心来看看,如有写错的地方也非常欢迎指正哦~(最近码字有点手瓢啊🤔),如果本文对你有帮助,还请点赞鼓励一下呀,毕竟码字和画图都不易啊。

DNS

域名系统(英语:Domain Name System,缩写:DNS)是互联网)的一项服务。它作为将域名相互映射的一个分布式数据库,能够使人更方便地访问互联网

引至维基百科 zh.wikipedia.org/wiki/%E5%9F…

域名相互映射: 指域名映射到其他域名或者IP,或者IP映射到域名

分布式数据库: 每一个域名服务器中都有一个数据库(解析记录表),其记录了当前域名服务器负责解析的域名的相关记录

DNS由 解析器域名服务器 组成的。域名服务器是指保存有该网络中所有主机的域名和对应IP地址,并具有将域名转换为IP地址功能的服务器。

现代的网络通信通常会使用到 域名+IP地址+MAC地址

而两台主机要进行通信就必须要知道对方的IP地址,通常我们访问一个网站就只是输入一个域名,例如 ww.baidu.com,那么计算机是如何知道这个域名对应的 IP 地址呢?这就是 DNS 协议要干的事情。

通过 IP 地址找到 MAC 地址是 ARP 协议干的事,本文不做详细解释。

域名

网域名称(英语:Domain Name,简称:Domain),简称域名网域,是由一串用点分隔的字符组成的互联网上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位。域名可以说是一个IP地址的代称,目的是为了便于记忆后者。例如,wikipedia.org是一个域名。人们可以直接访问wikipedia.org来代替IP地址,然后域名系统(DNS)就会将它转化成便于机器识别的IP地址。这样,人们只需要记忆wikipedia.org这一串带有特殊含义的字符,而不需要记忆没有含义的数字域名。

引至维基百科:zh.wikipedia.org/wiki/%E5%9F…

域名有明确的分级,根域名、顶级域名、二级域名、三级域名、四级域名...

域名的分级

❓ 那么域名由谁来规定和管理呢?不能是随便写吧?

全世界域名的最高管理机构,是一个叫做 ICANN (Internet Corporation for Assigned Names and Numbers)的组织,总部在美国加州。ICANN 负责管理全世界域名系统的运作

根域名

所有域名都是 根域名子域名,根域名为 .root,一般简写为 .。但是所有域名的根域名都是一样的,所以我们一般都省略根域名不写,DNS解析时计算机会自动为我们加上根域名。

举个🌰: www.baidu.com 的完整域名应该是 www.baidu.com. 或者 www.baidu.com.root

如果你尝试 ping www.baidu.com. 就会发现与 ping www.baidu.com 的ip是一样的

理论上,所有域名的查询都必须先查询根域名,因为只有根域名才能告诉你,某个顶级域名由哪台服务器管理。事实上也确实如此,ICANN 维护着一张列表(根域名列表),里面记载着顶级域名和对应的托管商。

顶级域名(一级域名)

先来讲讲顶级域名(TLD)。简单说,就是网址的最后一个部分。比如,网址www.baidu.com 的顶级域名就是 .com

ICANN 的一项主要工作,就是规定哪些字符串可以当作顶级域名。截至 2015 年 7 月,顶级域名共有 1058 个,它们大致可以分成两类:

  • 一类是通用顶级域名(gTLD),比如.com.net.edu.org.xxx等等,共有 700 多个。
  • 另一类是国家顶级域名(ccTLD),代表不同的国家和地区,比如.cn(中国)、.io(英属印度洋领地)、.cc( 科科斯群岛)、.tv(图瓦卢)等,共有 300 多个。

当然,ICANN 自己不会去管理这些顶级域名,因为根本管不过来。想想看,顶级域名有1000多个,每个顶级域名下面都有许多批发商,如果每个都要管,就太麻烦了。ICANN 的政策是,每个顶级域名都找一个托管商,该域名的所有事项都由托管商负责。ICANN 只与托管商联系,这样管理起来就容易多了。举例来说,.cn 国家顶级域名的托管商就是中国互联网络信息中心(CNNIC),它决定了 .cn 域名的各种政策。

二级域名(次级域名)

二级域名(Second Level Domain,SLD) 在通用顶级域名或国家顶级域名之下具有不同的意义:

  • 通用顶级域名下的二级域名:一般是指域名注册人选择使用的网上名称,如 yahoo.com(商业组织通常使用自己的商标、商号或其他商业标志作为自己的网上名称,如 baidu.com
  • 国家顶级域名下的二级域名:一般是指类似于通用顶级域名的表示注册人类别和功能的标志。例如,在 .com.cn 域名结构中,.com 此时是置于国家顶级域名 .cn 下的二级域名,表示中国的商业性组织,以此类推。

三级域名是形如 www.baidu.com 的域名,可以当做是二级域名的子域名,特征为域名包含两个 .。对于域名所有者/使用者而言,三级域名都是二级域名的附属物而无需单独费用。三级域名甚至不能称为域名,一般称之为域名下的 “二级目录”

除了二级域名,还有三级域名(www.baidu.com)、四级域名、...

网络上很大文章说 baidu.com 是顶级域名,这是错误的。

www.baidu.com的域名结构

域名服务器

域名服务器也就是我们常说的DNS服务器,是进行域名和与之相对应的IP地址转换的服务器。也就是说,域名服务器是用来对域名进行管理的,通常是由多个DNS服务器组成节点,对域名进行解析,指向你网站程序所放的服务器。

知道了域名的分级结构,全世界如此多的域名,那么域名服务器如何来处理如此多的域名解析请求呢?

所以域名服务器也采用了分级结构,相关的域名服务器只负责解析当前域名及其子域名。

根域名服务器

上面我们提到,ICANN 维护着一张根域名列表,里面记载着顶级域名和对应的托管商,其实根域名列表的正式名称是 DNS 根区(DNS root zone),保存 DNS 根区文件的服务器,就叫做 DNS 根域名服务器(root name server)。根域名服务器保存所有的顶级域名服务器的地址

由于早期的 DNS 查询结果是一个 512 字节的 UDP 数据包。这个包最多可以容纳 13 个服务器的地址,因此就规定全世界有 13 个根域名服务器,编号从 a.root-servers.net 一直到 m.root-servers.net。其中 10 台设置在美国,另外各有一台设置于荷兰、瑞典和日本。

前面我们说过,理论上所有域名的查询都必须先查询根域名,所以一般来说所有的域名服务器都会注册一份根域名服务器的 IP 地址的缓存,用于在必要的时候向其发送请求。

image.png

例如向根域名服务器查询 www.baidu.com 时,根域名服务器会返回 com 的顶级域名服务器的IP地址

顶级域名服务器

按照根域名服务器管理顶级域名的逻辑,顶级域名服务器显然就是用来管理注册在该顶级域名下的所有二级域名的,记录这些二级域名的 IP 地址

权限域名服务器

按照上面的逻辑,权限域名服务器应该是管理注册在二级域名下的所有三/四级域名的,但其实不是这样,如果一个二级域名或者一个三/四级域名对应一个域名服务器,则域名服务器数量会很多,我们需要使用划分区的办法来解决这个问题。那么权限域名服务器就是负责管理一个“”的域名服务器。

❓ 什么是区?怎样划分区呢?

区和域其实是不同的,区可以有多种不同的划分方法。以百度为例,我们假设有 fanyi.baidu.comai.baidu.comtieba.baidu.com 这三个三级域名。我们可以这样分区,fanyi.baidu.comtieba.baidu.com 放在 baidu.com 权限域名服务器,ai.baidu.com 放在 ai.baidu.com 权限域名服务器中。并且 baidu.com 权限域名服务器和 ai.baidu.com 权限域名服务器是同等地位的,而具体怎么分区是百度公司根据域名多少、访问多少等情况去自己规定的。

画个图直观理解一下:

image.png

本地域名服务器

除了上面三种 DNS 服务器,还有一种不在 DNS 层次结构之中,但是很重要的 DNS 服务器,就是本地域名服务器(也被称为权威域名服务器)。本地域名服务器是电脑解析时的默认域名服务器,即电脑中设置的首选 DNS 服务器和备选 DNS 服务器。

域名解析过程

解析记录

解析记录存储在域名服务器中,用于表达域名IP 之间的对应关系,称为 记录(record)。根据使用场景,"记录"可以分成不同的类型(type),下面列举几个常见的解析记录类型

type解释
A地址记录(Address),返回域名指向的IPv4地址。
AAAAAAAA记录(AAAA record),返回域名指向的IPv6地址。
NS域名服务器记录(Name Server),返回保存下一级域名信息的服务器地址。该记录只能设置为域名,不能设置为IP地址。
CNAME规范名称记录(Canonical Name),返回另一个域名,即当前查询的域名是另一个域名的跳转,详见下文。
MX邮件记录(Mail eXchange),返回接收电子邮件的服务器地址。

DNS服务器根据域名的层级,进行分级查询。

需要明确的是,每一级域名都有自己的NS记录,NS记录指向该级域名的域名服务器。这些服务器知道下一级域名的各种记录。

所谓"分级查询",就是从根域名开始,依次查询每一级域名的NS记录,直到查到最终的IP地址,过程大致如下。

  1. 从"根域名服务器"查到"顶级域名服务器"的NS记录和A记录(IP地址)
  2. 从"顶级域名服务器"查到"次级域名服务器"的NS记录和A记录(IP地址)
  3. 从"次级域名服务器"查出"主机名"的IP地址

仔细看上面的过程,你可能发现了,没有提到DNS服务器怎么知道"根域名服务器"的IP地址。回答是"根域名服务器"的NS记录和IP地址一般是不会变化的,所以"根域名服务器"的IP地址已经内置在所有DNS服务器里面了。

迭代查询

tips: 一般的DNS并不是全程使用迭代或者递归查询,而是使用两种方式结合。这里仅仅是为了演示全程使用迭代查询的过程。

迭代查询的过程其实就是:当域名服务器收到迭代查询请求报文时,需求给出主机“你下一步应当向哪一个域名服务器进行查询”的建议,然后由主机进行下一步的查询,当返回内容即没有确切的结果也没有下一步的建议时,DNS失败。

这里的建议指 NS 或者 CNAME 等记录

请看图(随手画的小度机器人)

迭代查询过程

可以通过 dig 命令来迭代跟踪DNS过程,windows下 dig 命令的安装请自行百度

dig +trace www.baidu.com

注意:这里客户端如何选择多条 NS 记录中的一条记录进行下一次查询的目标在不同的操作系统中是不一样的,有的系统会选择第一条,有的则会随机选择。所以一般 DNS服务器 都会将最快的 NS 记录放到第一条。

当返回多条 NS 记录时,如果访问的第一条 NS 记录的 IP 查询时,一定时间内无响应,则会开始尝试访问其他 NS 记录的 IP 查询。

如果返回的记录为空,则代表查询失败,结束 DNS 过程。

递归查询

所谓递归查询就是:如果主机所询问的本地域名服务器不知道被查询的域名的 IP地址,那么本地域名服务器就以 DNS 客户的身份,向其它根域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。因此,递归查询返回的查询结果是所要查询的 IP地址 ,或者是报错,表示无法查询到所需的 IP地址

主机对域名服务器说:你给我查 www.baidu.comip,我不管你怎么查,你要是不知道你就自己去问其他人,我只要结果不要过程🐅。

当然,图还是要上的。

递归查询

实际的DNS查询过程

上面有特别提到,实际的 DNS查询 并不是单纯的迭代或者递归查询,而是相互结合使用,那么什么时候使用递归什么时候使用迭代呢?

主机向本地域名服务器发起的是递归查询,本地域名服务器到其他域名服务器发起的是迭代查询。

递归+迭代.jpg

由于 www.baidu.com 的解析过程中需要经过一条 CNAME 记录 www.a.shifen.com,我想大家到现在也已经清楚 CNAME 记录的作用了,后面的例子中我就以 baidu.com 而不是 www.baidu.com 来举例了。(偷懒 )

这里你会发现baidu.com 和 shifen.com 的授权域名服务器是同一台,这就是上面说的在同一个

DNS缓存

为了缓解各个域名服务器的查询压力和加快 DNS 查询速度,浏览器、操作系统、域名服务器都会将 DNS 的查询结果进行缓存,当在缓存有效时间内再次收到重复的 DNS 请求时,就会直接返回 IP 地址,而不会继续下一步的域名查询了。

缓存的优先级由 DNS 查询的路径来定,相信这个很好理解

浏览器缓存>操作系统缓存> hosts 文件>本地DNS服务器缓存>根域名服务器缓存>...

缓存时长如何控制

缓存时间一般由 DNS响应报文资源记录部分 中的 TTL (Time to live)指定的值,单位为秒

    baidu.com: type A, class IN, addr 220.181.57.216         #资源记录部分
        Name: baidu.com                                      #域名字段, 这里请求的域名为baidu.com
        Type: A (Host Address) (1)                           #类型字段, 这里为A类型
        Class: IN (0x0001)                                   #类字段
        Time to live: 5                                      #生存时间
        Data length: 4                                       #数据长度
        Address: 220.181.57.216                              #资源数据, 这里为IP地址

但是有些浏览器或者操作系统会因为 TTL 值过小或者其他的原因不遵守 TTL 约定的缓存时间。这也导致很多缓存问题的 TTL 解决方案失效。

hosts文件并不是缓存,所以它是永久有效的

DNS使用UDP还是TCP

DNS 同时使用 TCPUDP 协议的 53 号端口。这种单个应用协议同时使用两种传输协议的情况在 TCP/IP 栈也算是个另类。但很少有人知道 DNS 分别在什么情况下使用这两种协议。

DNS区域传输 (同步解析记录)和 DNS 响应大于 UDP 报文最大长度的时候使用 TCP 协议,其他时候使用 UDP 协议。

为什么使用UDP

快,是UDP的最大优势

客户端向 DNS 服务器查询域名,一般返回的内容都不超过 512字节 ,用 UDP 传输即可。不用经过三次握手,这样 DNS 服务器负载更低,响应更快。

理论上说,客户端也可以指定向 DNS 服务器查询时用 TCP,但事实上,很多 DNS 服务器进行配置的时候,仅支持 UDP 查询包。

何时使用TCP

传输数据大于UDP最大报文长度的时候使用TCP协议:

首先了解一下 TCPUDP 传送字节的长度限制:

UDP 报文的最大长度为 512 字节,而 TCP 则允许报文长度超过 512 字节。当 DNS 查询超过 512 字节时会将后面的数据部分丢掉,所以这时需要使用 TCP 发送。但是通常传统的 UDP 报文一般不会大于 512 字节。即使 DNS 服务器中符合条件的记录很多, DNS 服务器也会限制最多返回 13条 来防止报文大于 512 字节。

DNS区域传输的时候使用TCP协议:

DNS的规范规定了 2 种类型的 DNS 服务器,一个叫 主 DNS 服务器,一个叫 辅助DNS服务器。 在一个 主 DNS 服务器 从自己本机的数据文件中读取该区的 DNS 数据信息,而 辅助DNS服务器 则从区的 主 DNS 服务器 中读取该区的 DNS 数据信息。当一个 辅助 DNS 服务器 启动时,它需要与 主 DNS 服务器 通信,并加载数据信息,这就叫做 区传送(zone transfer)

辅域名服务器会定时(一般 3 小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传输,进行数据同步。区域传输使用 TCP 而不是 UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多,且需要保证数据的 可靠性完整性

CDN中DNS的应用

CDN 是前端优化加载速度的常用方案,那到底什么是 CDN,它又是如何优化加载速度的呢?

CDN 的全称是 Content Delivery Network,即内容分发网络。其目的是通过在现有的internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络边缘,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。

CDN 的原理很简单

当用户访问 CDN 的资源时,首先也是需要经过 DNS 解析过程

CDN 就是在 DNS 解析时,其内部的 DNS 智能调度系统通过负载均衡、网路等情况来选择出与主机最合适的资源服务器的 IP 作为 DNS 解析结果

image-20211128214438404.png

CDN缓存

浏览器本地缓存失效后,浏览器会向 CDN 边缘节点发起请求。类似浏览器缓存,CDN 边缘节点也存在着一套缓存机制。

CDN缓存的缺点

CDN 的缓存不仅减少了用户的访问延时,也减少的源站的负载。但其缺点也很明显:当网站更新时,如果 CDN 节点上数据没有及时更新,即便用户再浏览器使用 Ctrl+F5 的方式使浏览器端的缓存失效,也会因为 CDN 边缘节点没有同步最新数据而导致用户访问异常。

CDN的缓存机制

CDN 边缘节点缓存策略因服务商不同而不同,但一般都会遵循 http标准协议,通过 http响应头 中的Cache-control: max-age 的字段来设置 CDN 边缘节点数据缓存时间。

当客户端向 CDN 节点请求数据时,CDN 节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN 节点就会向源站发出回源请求,从源站拉取最新数据,更新本地缓存,并将最新数据返回给客户端。所以,如果我们修改了内容,最好加个版本号,来容 CDN 重新获取资源,从而减少不必要的麻烦,比如 :

app.js?v=20171114 或者 style.css?v=20171114

CDN缓存刷新

CDN 边缘节点对开发者是透明的,相比于浏览器 Ctrl+F5 的强制刷新来使浏览器本地缓存失效,开发者可以通过 CDN 服务商提供的 刷新缓存 接口来达到清理 CDN 边缘节点缓存的目的。这样开发者在更新数据后,可以使用 刷新缓存 功能来强制 CDN 节点上的数据缓存过期,保证客户端在访问时,拉取到最新的数据。

DNS相关的大厂面试题

DNS查询的完整过程是怎么样的?

  1. 浏览器将会检查缓存中有没有这个域名对应的解析过的 IP 地址,如果有该解析过程将会结束。浏览器缓存域名也是有限制的,包括缓存的时间、大小,可以通过 TTL 属性来设置。

  2. 如果用户的浏览器中缓存中没有,操作系统会先检查自己本地的 DNS 解析器缓存和 hosts 文件是否有这个网址映射关系,如果有,就先调用这个 IP 地址映射,完成域名解析。

  3. 如果都没有,会找 TCP/IP 参数中设置的首选 DNS 服务器,我们叫它本地 DNS 服务器。通过递归查询的方式向本地 DNS 服务器发起查询,如果本地 DNS 服务器中有 A记录 或者该域名的映射缓存,则返回

  4. 如果都没有,本地域名服务器会开始迭代查询的过程,会先向 13 台根域名服务器查询该域名,根域名服务器会返回该域名的顶级域名服务器的 IP 地址,也就是 NS 记录。然后本地域名服务器再向顶级域名服务器发起查询,顶级域名服务器返回二级域名服务器的 NS 记录,重复这个过程直到返回 A 记录为止,最后把 A 记录中的 IP 地址返回给主机

说说递归查询和迭代查询?以及他们的优缺点?什么时候使用递归查询什么时候使用迭代查询?

DNS 是基于 UPD 还是 TCP 协议的?什么时候使用 UPD 什么时候使用 TCP?

CDN知道吗?它的原理是什么呢?

码字画图都不易,你点赞了吗?(关键题)😃欢迎补充你遇到的DNS相关的面试题

参考文章:

超详细DNS解析

一文看懂CDN加速原理