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

不要看一个人说了什么,而要看这个人做了什么

前言

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

  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. 网络是如何连接的

看都看到这里了,那就劳烦,动动小手手,一键三连哇

猜你喜欢

转载自juejin.im/post/7083040190549196830