网络拾遗之 DNS协议:网络世界的地址簿

2022-08-25 14:32:15 浏览数 (1)

前言

大家好,我是柒八九。今天我们继续来讲述一下,针对网络通信方面的东西。在前几篇文章

  1. 网络通信之生成HTTP消息
  2. 网络通信之IP地址

我们讲到,客户端要和服务端进行通信,需要在「客户端」(一般为浏览器)进行数据信息的封装。如下格式。

请求消息格式

尽管浏览器能够解析网址并生成 HTTP 消息,但它本身并不 具备将消息发送到网络中的功能,客户端会「委托」操作系统,调用对应的协议栈,进行数据封装等操作。然后发送出去。

然后,还介绍了,「IP」地址的一些概念。从而得知,「IP 地址是一个网卡在网络世界的通讯地址,相当于我们现实世界的门牌号码」。也就是说,我们之所以能肆无忌惮的在网络中遨游,需要仰仗 IP 地址。

但是,在现实生活中,我们访问一个资源的时候,并不会通过那些晦涩难懂的 IP 地址。而是,通过域名来访问。例如,我们在通过百度查询一个关键的时候,不是通过百度的那一长串的IP地址,而是直接在浏览器中输入www.baidu.com进行信息的检索。

那么,我们今天就来谈谈网络世界中,是如何将这个一个过程实现的。

「时间不早了,干点正事哇」

简明扼要

  1. 通过 DNS 查询 IP 地址的操作称为「域名解析」
  2. Socket 库是用于「调用网络功能」的程序组件集合
  3. 根据域名查询 IP 地址时,浏览器会使用 Socket 库中的「解析器」
  4. 客户端的查询消息包含以下 3 种信息 1. 「域名」 2. 「Class」(IN) 3. 「记录类型」
  5. DNS 服务器会从域名与 IP 地址的「对照表」中查找相应的记录,并返回 IP 地址
  6. 在域名中,「越靠右的位置表示其层级越高」
  7. 在互联网中,comcn 的上面还有一级域,称为「根域」
  8. 「根域」的 DNS 服务器中保管着 comcn 等的 DNS 服务器的信息
  9. DNS 服务器是一个「树状的层次结构」 从上到下一次为 1. 根 DNS 服务器 2. 顶级域 DNS 服务器 3. 权威 DNS 服务器

❝面试点: 1. 通过 DNS 查询 IP 地址的操作称为「域名解析」 2. 客户端的查询消息包含以下 3 种信息: 「域名」/「Class」/「记录类型」 3. DNS 服务器会从域名与 IP 地址的「对照表」中查找相应的记录,并返回 IP 地址 4. 根域的 DNS 服务器中保管着 comcn 等的 DNS 服务器的信息 ❞

文章概要

  1. Socket 库提供查询 IP 地址的功能
  2. 解析器向 DNS 服务器发出查询
  3. DNS 服务器的工作步骤
  4. 域名的层次结构
  5. 寻找相应的 DNS 服务器并获取 IP 地址
  6. 负载均衡

1. Socket 库提供查询 IP 地址的功能

查询 IP 地址的方法非常简单,只要询问「最近」的 DNS 服务器“www. wl.com 的 IP 地址是什么”就可以了,DNS 服务器会回答说“该 服务器的 IP 地址为 xxx.xxx.xxx.xxx”。

向 DNS 服务器发出查询,也就是向 DNS 服务器发送查询消息,并接 收服务器返回的响应消息。对于 DNS 服务器,我们的计算机上 一定有相应的 「DNS 客户端」,而相当于 DNS 客户端的部分称为 DNS 解析器,或者简称「解析器」

❝通过 DNS 查询 IP 地址的操作称为「域名解析」

解析器实际上是一段程序,它包含在操作系统的 Socket 库中。库就是一堆通用程序组件的「集合」。Socket 库也是一种库,其中包含的程序组件,可以让其他的应用程序调用「操作系统」的网络功能,而解析器就是这个库中的其中一种程序组件。

❝Socket 库是用于「调用网络功能」的程序组件集合 ❞

2. 解析器向 DNS 服务器发出查询

解析器的调用方法

调用解析器后,解析器会向 DNS 服务器发送查询消息,然后 DNS 服务器会返回响应消息。响应消息中包含查询到的 IP 地址,解析器会取出 IP 地址,并将其写入浏览器指定的「内存地址」中。

接下来,浏览器在向 Web 服务器发送消息时,只要从该内存地址取出 IP 地址,并将它与 HTTP 请求消息一起交给操作系统就可以了。

❝根据域名查询 IP 地址时,浏览器会使用 Socket 库中的「解析器」

解析器的内部原理

浏览器调用解析器时,程序的控制流程就会转移到解析器的「内部」。当到达 需要调用解析器的部分时,对应的那一行程序就会被执行,浏览器本身的工 作就会暂停(「①」,这步是「阻塞性」)。然后,Socket 库中的解析器开始运行(「②」),完成应用程序委托的操作。原本运行的程序进入「暂停状态」,而被调用的程序开始运行。

然后,解析器会生成要发送给 DNS 服务器的查询消息。「这个过程与浏览器生成要发送给 Web 服务器的 HTTP 请求消息的过程类似」。解析器会「根据 DNS 的规格」,生成一条表示“请告诉我 xxxx 的 IP 地址”的数据,并将它发送给 DNS 服务器(「③」)。发送消息这个操作「并不是」由解析器自身来执行,而是要「委托」给操作系统内部的「协议栈」来执行。「解析器本身不具备使用网络收发数据的功能」

协议栈会执行发送消息的操作,然后通过「网卡」将消息发送给 DNS 服务器 (「④⑤」)。当 DNS 服务器收到查询消息后,它会根据消息中的查询内容进行查 询。然后,和发送经过的步骤一致,返回的消息也是按照「原来的路线返回」。(「⑥⑦⑧⑨」)。

「最后」,解析器会将取出的 IP 地址写入应用程序指定的「内存地址中」

3. DNS 服务器的工作步骤

DNS 服务器的基本工作就是「接收来自客户端的查询消息」,然后「根据消息的内容返回响应」

来自客户端的查询消息包含以下 「3 种信息」

类型

描述

「域名」

服务器、邮件服务器(邮件地址中 @ 后面的部分)的名称

「Class」

Class 的值「永远」是代表互联网的 「IN」

「记录类型」

表示域名对应「何种类型」的记录 类型为 「A」 时:表示域名对应的是 「IP 地址」 类型为 「MX」 时:表示域名对应的是邮件服务器

「A 是 Address 的缩写」 /「MX:Mail eXchange,邮件交换的缩写」

DNS 服务器上「事先保存」有前面这 3 种信息对应的记录数据。

DNS 服务器的基本工作

例如,如果要查询 www.wl.com 这个域名对应的 IP 地址,客 户端会向 DNS 服务器发送包含以下信息的查询消息。

信息

域名 = www.wl.com

Class = IN

记录类型 = A

然后,DNS 服务器会从「已有的记录」中查找域名、Class 和记录类型「全部匹配」的记录。

当记录类型为 MX 时,DNS 服务器会在记录中保存「两种」信息,分别是「邮件服务器的域名」「优先级」

❝DNS 服务器会从域名与 IP 地址的对照表中查找相应的记录,并返回 IP 地址 ❞

实际上还有很多其他的类型。

  • 根据 IP 地址「反查域名」PTR 类型
  • 查询域名相关「别名」CNAME类型
  • 查询 DNS 服务器 IP 地址的 NS 类型
  • 以及查询「域名属性信息」SOA 类型等

4. 域名的层次结构

互联网中存在着不计其数的服务器,将这些服务器的信息全部保存在一台 DNS 服务器中是不可能的,因此一定会出现在 DNS 服务器中找不到要查询的信息的情况。

需要将信息分布保存在「多台」 DNS 服务器中,这些 DNS 服务器相互接力配合,从而查找出要查询的信息。

信息是如何在 DNS 服务器上注册

首先,DNS 服务器中的所有信息都是「按照域名以分层次的结构」来保存的。DNS 中的域名都是用「句点来分隔」的,比如 www.wl.com,这里的句点代表了不同层次之间的界限。

在域名中,「越靠右的位置表示其层级越高」。比如 www.wl.com 这个域名如果按照公司里的组织结构来说,大概就是“com 事业集团 wl 部 的 www”这样。其中,相当于一个层级的部分称为域。因此,com 域的下一层是 wl 域,再下面才是 www 这个名字。

这种「具有层次结构」的域名信息会注册到 DNS 服务器中,而「每个域」都是作为「一个整体」来处理的。换句话说就是,一个域的信息是作为一个整体存放在 DNS 服务器中的,不能将一个域拆开来存放在多台 DNS 服务器中。(不过,DNS 服务器和域之间的关系也并不总是一对一的,一台 DNS 服务器中也可以存放多个域的信息。)

于是,「DNS 服务器也具有了像域名一样的层次结构」,每个域的信息都存放在相应层级的 DNS 服务器中。

5. 寻找相应的 DNS 服务器并获取 IP 地址

这里的关键在于「如何找到我们要访问的 Web 服务器的信息归哪一台 DNS 服务器管」

首先,将负责「管理下级域」的 DNS 服务器的 「IP 地址」注册到它们的「上级 DNS 服务器中」,然后上级 DNS 服务器的 IP 地址再注册到更上一级的 DNS 服务器中,以此类推。

例如,负责管理 bcnz.wl.com 这个域的 DNS 服务器的 IP 地址需要注册到 wl.com 域的 DNS服务器中,而 wl.com 域的 DNS 服务器的 IP 地址又需要注册到 com 域的 DNS 服务器中。这样,我们就可以通过上级 DNS 服务器查询出下级DNS 服务器的 IP 地址,也就可以向下级 DNS 服务器发送查询请求了。

comcn 这些域(称为顶级域),它们「各自负责」保存下级 DNS 服务器的信息。在互联网中,comcn 的上面还有一级域,称为「根域」。根域不像 com、cn 那样有自己的名字,因此在一般书写域名时经常被省略,如果要明确表示根域,应该像 www.wl.com. 这样在域名的「最后再加上一个句点」,而这个最 后的句点就代表根域。

树状的层次结构

❝根域的 DNS 服务器中保管着 comcn 等的 DNS 服务器的信息 ❞

除此之外还需要完成另一项工作,那就是将根域的 DNS 服务器信息保存在互联网中「所有」的 DNS 服务器中。客户端只要能够找到任意一台DNS 服务器,就可以通过它找到根域 DNS 服务器,然后再一路顺藤摸瓜找到位于下层的某台目标 DNS 服务器。

分配给根域 DNS 服务器的 IP 地址在全世界「仅有 13 个」 ,而且这些地址几乎不发生变化。

DNS 解析流程

  1. 电脑客户端会发出一个 DNS 请求,问 www.wl.com 的 IP 是啥啊,并发给本地域名服务器 (「本地 DNS」)。如果是通过 DHCP 配置,本地 DNS 由你的网络服务商(ISP),如电信、移动等自动分配,它通常就在你网络服务商的某个机房。
  2. 「本地 DNS」 收到来自客户端的请求。然后,查找对应的记录信息。如果能找到 www.wl.com,它直接就返回 IP 地址。如果没有,本地 DNS 会去问它的「根域名服务器」。根域名服务器是「最高层次」的,全球共有 13 套。它不直接用于域名解析,但能指明一条道路。
  3. 「根 DNS」 收到来自本地 DNS 的请求,发现后缀是 .com,说:“www.wl.com 啊,这个域名是由.com 区域管理,我给你它的「顶级域名服务器的地址」,你去问问它吧。”
  4. 「本地 DNS」 转向问顶级域名服务器:“你能告诉我 www.wl.com 的 IP 地址吗?”顶级域名服务器就是大名鼎鼎的比如 .com、.net、 .org 这些一级域名,它负责管理二级域名,比如 wl.com,所以它能提供一条更清晰的方向。
  5. 「顶级域名服务器」说:“我给你负责 www.wl.com 区域的「权威 DNS 服务器」的地址,你去问它应该能问到。”
  6. 「本地 DNS」 转向问权威 DNS 服务器:“www.wl.com 对应的 IP 是啥呀?”wl.com 的权威 DNS 服务器,它是域名解析结果的原出处。为啥叫权威呢?就是我的域名我做主。
  7. 「权威 DNS 服务器」查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
  8. 本地 DNS 再将 IP 地址「返回客户端」,客户端和目标建立连接。

通过缓存加快 DNS 服务器的响应

有时候并不需要从最上级的根域开始查找,因为 DNS 服务器有一个「缓存功能」,可以记住之前查询过的域名。

如果要查询的域名和相关信息「已经在缓存」中,那么就可以直接返回响应,接下来的查询可以从缓存的位置开始向下进行。相比每次都从根域找起来说,缓存可以减少查询所需的时间。

这个缓存机制中有一点需要注意,那就是信息被缓存后,原本的注册信息可能会「发生改变」,这时缓存中的信息就有可能是不正确的。因此,DNS 服务器中保存的信息都设置有一个「有效期」,当缓存中的信息超过有效期后,数据就会从缓存中删除。

6. 负载均衡

站在客户端角度,这是「一次 DNS 递归查询过程」。因为本地 DNS 全权为它效劳,它只要坐等结果即可。在这个过程中,DNS 除了可以通过「名称映射为 IP 地址」,它还可以做另外一件事,就是「负载均衡」

DNS 首先可以做「内部负载均衡」

例如,某个应用要访问另外一个应用,如果配置另外一个应用的 IP 地址,那么这个访问就是「一对一」的。但是当被访问的应用撑不住的时候,我们其实可以部署多个。但是,访问它的应用,如何在多个之间进行负载均衡?只要「配置成为域名」就可以了。在域名解析的时候,我们只要「配置策略」,这次返回第一个 IP,下次返回第二个 IP,就可以实现负载均衡了。

DNS 还可以做「全局负载均衡」

为了保证我们的应用「高可用」,往往会部署在多个机房,「每个地方都会有自己的 IP 地址」。当用户访问某个域名的时候,这个 IP 地址可以「轮询访问多个数据中心」。如果一个数据中心因为某种原因挂了,只要在 DNS 服务器里面,将这个数据中心对应的 IP 地址删除,就可以实现一定的高可用。

  1. 当一个客户端要访问 object.wl.com 的时候,需要将域名转换为 IP 地址进行访问,所以它要「请求本地 DNS 解析器」。(步骤1)
  2. 本地 DNS 解析器先查看看「本地的缓存是否有这个记录」。如果有则直接使用,因为上面的过程太复杂了,如果每次都要递归解析,就太麻烦了。(步骤2)
  3. 如果本地无缓存,则需要请求本地的 DNS 服务器。(步骤3)
  4. 本地的 DNS 服务器一般部署在你的数据中心或者你所在的运营商的网络中,本地 DNS 服务器也需要看本地是否有缓存,如果有则返回,因为它也不想把上面的递归过程再走一遍。(步骤4)
  5. 5 至 7. 如果本地没有,本地 DNS 才需要「递归」地从根 DNS 服务器,查到.com「顶级域名服务器」,最终查到 wl.com 的「权威 DNS 服务器」,给本地 DNS 服务器,权威 DNS 服务器按说会返回真实要访问的 IP 地址。(步骤5-7) 对于不需要做全局负载均衡的「简单应用」来讲,wl.com 的权威 DNS 服务器可以直接将 object.wl.com 这个域名解析为「一个或者多个 IP 地址」,然后「客户端」可以通过多个 IP 地址,进行简单的轮询,实现「简单的负载均衡」 但是对于「复杂的应用」,尤其是跨地域跨运营商的大型应用,则需要更加复杂的全局负载均衡机制,因而需要「全局负载均衡器」GSLB,Global Server Load Balance)专门的设备或者服务器来做这件事情。
  6. 「第一层 GSLB」,通过查看请求它的本地 DNS 服务器所在的运营商,就知道用户所在的运营商。假设是移动,通过 CNAME 的方式,通过「另一个别名」 object.yd.wl.com,告诉「本地 DNS 服务器」去请求第二层的 GSLB
  7. 「第二层 GSLB」,通过查看请求它的本地 DNS 服务器所在的地址,就知道用户所在的「地理位置」,然后将「距离用户位置比较近」的 Region 里面,六个内部负载均衡(SLB,Server Load Balancer)的地址,返回给本地 DNS 服务器

后记

分享是一种态度,这篇文章,主要的篇幅来自于《网络是如何连接的》,算是一个自我学习过程中的一种记录和总结。主要是把自己认为重要的点,都罗列出来。同时,也是为大家节省一下排雷和踩坑的时间。当然,可能由于自己认知能力所限,有些点,没能表达的很好。

参考资料:

  1. 趣谈网络协议
  2. 网络是如何连接的

0 人点赞