阅读 3765

「一道面试题」输入URL到渲染全面梳理上-网络通信篇

写在前面

此文是一道面试题,又不仅仅是一道面试题

从输入 URL 到页面渲染发生了什么?比如在浏览器输入了 www.qq.com 后浏览器是怎么把最终的页面呈现,这是一个非常经典的面试题,不管是大公司还是小公司甚至前端或后端的面试中命中率都极高,因为涉及到的知识点和可挖掘的地方比较多,而且这中间几乎每一步都是可以优化的

既然大家刷到了这篇帖子,希望大家花点时间耐心看完,不会让你失望的,此文从网络五层模型详解析及浏览器页面渲染机制等多方面来认识URL从输入到页面渲染的整个过程,内容还是很充实的

写着写着发现有点长,就分成三篇了 😄

前两篇文章都是帮助大家理解整个过程,所以并没有直接给出答案,而是给大家梳理解释一些相关琐碎的知识,目的不是答题,而是彻底理解此间流程,大家只要认真看到最后一篇就可以骄傲的回答这道题了,自己心中给自己一个答案,再看最后一篇我个人通过这些知识总结的答案 ( 如果你的总结更加充实/细致,请在评论区分享出来,我们一起查漏补缺 ) ,先看后思考,再总结相互讨论,效果最佳

URL从输入到页面渲染这整个过程可以分为 网络通信页面渲染 两个方面,一般后端程序猿回答这个问题侧重网络通信就行了,但是前端页面渲染也得了解,总之回答的越详细分值越高

那么开始吧,这篇文章我们先来看网络通信方面,可能前端同学大家对网络方面的认知应该没有后端同学强,其实这道面试题最能突出自己的也是网络方面,因为它涉及到了很多网络通信原理的知识,所以这块咱们慢慢梳理

网络分层的由来

不晓得大家知不知道网络分层,网络其实有很多层,层与层之间又有好多协议存在,还有各种各样的数据包,这玩意干巴巴的,很没意思,这么多层太麻烦了,为什么有这么多层呢?为什么不直接一层呢?

起初计算机与计算机之间的通信只需要一根线就可以完成通信,但是世界那么大,那么多计算机,距离太远了,而且这线还老容易被无良的人偷偷剪断

后来就出来了无线网,虽然其中网关、路由之间也需要连线,但不是让每台计算机两两连接,而是一个区域为单位计算机相互连接通信

后来发现计算机之间的连线只能传送0/1信号,另一台计算并不知道那么多0/1代表什么,就像 010101010101111000111011010 你知道这一大串是什么意思吗,计算机也不知道,不同厂商生产的计算机连线实现通信也是很麻烦的,干脆定义一套规则吧,不管是哪个牌子的计算机,都必须遵守这套规则,这套规则就是我们经常说的 网络协议

哦哦,是在说 网络分层 ,不是讲 网络协议 ,继续继续,接着我们上面的话题,问题来了,计算机之间通过连线传送0/1信号的问题虽然规定了通信规则,但是除了像0/1这种无意义的信号之外,网络中还存在着其他各种各样的问题

  • 两个计算机之间怎么进行识别?
  • 怎么才能知道对方的地址?
  • 不同计算机应用程序怎么知道是给自己传递的数据?
  • 不同的通信数据格式怎么来规定等等一系列的问题

如果各种问题都写成一套协议来规定双方通信的规则,但是万一其中哪些规则通信中出现问题,影响到了其他规则,最常见的就是数据包,一个数据包中如果包含各种各样的协议,呀呀呀

如果我们对网络进行分层,每一层负责一项具体的工作,然后把数据传送到下一层,那么往来通信和网络互联这一复杂的问题是不是就变得较为简单化了呢

可能大家没有太明白,没关系,接着看

TCP/IP五层模型

既然要分层,那么分为几层才好呢?

目前的网络层次可划分为 四层因特网协议栈七层因特网协议栈 ,其实起初网络分层是标准的七层,也就是我们所说的 OSI 七层模型 ,参考模型是国际标准化组织 ISO 制定的一个用于计算机或通信系统间互联的标准体系,一般称为 OSI参考模型七层模型

可能对网络有些了解的同学知道还有 TCP/IP 四层模型TCP/IP 五层模型 ,这又是怎么出来的呢?

其实所谓的 TCP/IP 四层模型TCP/IP 五层模型 是以 OSI 七层 优化而来,把某些层进行合并了,本质上还是相同的,OSI七层模型 太过细化,有一定的参考意义,但实现起来比较繁琐,相比较而言,TCP/IP模型 比较简洁,具有较强的实际应用价值

我们来看一个模型的图片 ( 网图侵删 )

image-20200407141628775

TCP/IP 将计算机网络分成了四个层次,一般资料或教程里都是结合 OSI7层模型TCP/IP4层模型,将计算机网络按照5层的模型来讲,5层模型只是为了方便介绍计算机网络原理而设计的,而在实际应用中还是 TCP/IP四层模型 ,这点大家要明白

这里我们同样用五层来解释,比较好理解些,当然,这里只能让大家脑海里有一个具体的网络分层结构的认知,作为面试回答了解这些足够,而后推荐大家继续深入,可以看相关的书籍和资料,此文也能够起到一个引导的作用

PS: 作为一个前端或者是后端,我们都是软件开发,所以侧重点放在网络层以上就可以了,物理层和数据链路层都是硬件相关的,所以这两个层下面不会过多叙述,了解即可

物理层

物理层,顾名思义,通过物理手段 ( 网线,光纤,无线 ) 将设备连接在一起,传输0/1电信号 ( 也叫比特流 ) ,就像我们上边讲到的计算机之间的物理连线

主要用来传输0/1信号,因为0/1信号没有任何的现实意义,所以用另一层用来规定不同0/1组合的意义

数据链路层

还是上面说的,010101010101111000111011010 ,像这么一串数据计算机并不知道是什么意思

下层的物理层不能规定不同0/1组合的信号代表什么意义,所以在数据链路层规定了一套协议,专门给0/1信号进行分组,规定不同的组代表的是什么意思,从而让双方计算机都能够进行识别,这个协议就是我们常说的 以太网协议

以太网协议

以太网协议规定一组电信号构成一个数据包,我们把这个数据包称为 ,每一个帧由 标头数据 两部分组成

帧的大小一般为 64 - 1518 个字节 较大的数据则需要分成多个桢

标头 Head ,18个字节组成,标头中包含这个 是由谁发送、发送给谁这些信息,所以标头主要是一些说明数据 例如发送者/接受者等信息

数据 Data ,46-1500个字节组成,里面主要是发送者想给接收者的内容

把一台计算机的数据通过物理层和数据链路层发送给另外一台计算机,怎么标识对方以及怎么知道对方的地址呢? 唯一标示 MAC地址 出现了

MAC地址

进入网络的每一台计算机,都会有网卡接口,每一个网卡都会有一个唯一的地址,就是所谓的 MAC地址 ,它就是网络中每台计算机设备的唯一标识,是一串由48个字节组成的十六进制数,每台计算机在厂商生产出来的时候就标识好了,所以我们用 MAC地址 来标识对方

再来看一个图 ( 网图侵删 )

image-20200407141654052

如上图所示,如计算机A知道了计算机B的MAC地址,然后计算机A想要给计算机B传送数据,虽然计算机A知道了计算机B的MAC地址,可是A要怎么给B传送数据呢?

计算机A不仅连着计算机B,而且计算机A也连接着计算机C和D,虽然计算机A知道计算机B的MAC地址,但是却不知道B是在哪一路上,所以为了解决这个问题,广播 这个概念就出现了

广播

在同一子网络,就是我们常说的局域网中,计算机通过广播来通信,即向同子网中全部计算机发送数据包,其它计算机根据数据包中接收者的 MAC地址 来判断是否接收数据包

通俗来讲,就是A会同时给B/C/D发送数据包,这个数据包中会包含着接收者的 MAC地址 信息,当B/C/D接收到了数据包,会取出数据包中的 MAC地址 与自身的 MAC地址 对比,如相同就接收这个数据包,否则就丢弃这个数据包 ( 丢包 ),这种方式我们称之为 广播

就像,你和女友在人群中走散了,你大喊一声她的名字,听到的人会自己匹配,是自己就会理会,不是自己就当你是傻子不理你

那么到了目前,我们知道了计算机之间的标示和如何通信,但是还有一个问题,要怎么知道对方的 MAC地址 呢 ?这又牵出了 ARP协议 ,通过 ARP协议 来得知对方的 MAC地址 ,这个协议是网络层的一个协议,所以我们暂且搁置,先接着往下看

网络层

看了物理层和数据链路层的作用,可能大家会觉得好像已经可以完成正常通信了,那么网络层又是做什么的呢?

其实我们所处的网络,是由无数个子网络 ( 局域网 ) 构成的,广播的时候,也只有同一个子网里的计算机能够收到,如过没有子网这种东西,计算机A通过广播的方式发一个数据包给计算机B,那么全世界所有的计算机都能收到这个数据包,然后进行对比再舍弃,那么多台计算机后果可想而知,子网也因此而产生

那么问题又来了,我们要怎么区分 Mac地址 是属于同一个子网的呢?假如是同一个子网,我们就用广播的形式把数据传送给对方,如果不是同一个子网的,我们就会把数据发给网关,让网关进行转发

怎么判断两台计算机是否在同一个子网中呢,这就是网络层干的事情,为了解决这个问题,就有了 IP协议 的概念

IP协议

IP协议所定义的地址,就是我们常说的 IP地址IP协议 有两个版本,ipv4 / ipv6,目前用的最多的还是ipv4,这个地址由32位的二进制数组成,我们一般把它分成4段的十进制表示,地址范围在 0.0.0.0 ~ 255.255.255.255 ,这个我们应该都很常见

每一台想要联网的计算机都会有一个 IP地址 ,这个 IP地址 分为两部分,前面一部分代表网络,后面一部分代表主机,但是网络部分和主机部分所占用的二级制位数是不固定的

假如两台计算机的网络部分是一模一样的,我们就说这两台计算机是属于同一个子网 ( 局域网 ) 中,例如 192.168.17.1192.168.17.2 , 假如这两个 IP地址 的网络部分为 24 位,主机部分为 8 位,那么他们的网络部分都为 192.168.43 , 所以我们说这两台计算机处于同一个子网中

问题又随之而来了,给我们两个 IP地址 ,鬼知道网络部分占几位,主机部分又占几位呢?

这就又引出了我们另一个关键词 子网掩码

子网掩码

子网掩码IP地址 一样也是32位二进制数,但是它的网络部分规定全部为1,主机部分规定全部为0,也就是说假如上面那两个 IP地址 的网络部分为24位,主机部分为8位的话,那他们的子网掩码为

11111111.11111111.11111111.00000000 ,也就是 255.255.255.0

有了子网掩码,怎么来判断 IP地址 是否处于同一个子网中呢?

显然,知道了子网掩码,相当于我们知道了网络部分是几位,主机部分是几位,我们只需要把 IP地址 与他的子网掩码做一个 ( and ) 运算,然后把各自的结果进行比较就行了,如果比较的结果相同,则代表的是同一子网,否则不是同一子网

也就是说有了两台计算机的 IP地址子网掩码 ,我们就可以判断他们是否处在同一子网当中了

假设他们处在同一子网当中,计算机A要和计算机B发送数据时,我们通过是 ARP协议 来得到计算机的 MAC地址

ARP协议

ARP协议 也是通过广播的形式,给同一个子网中每个电脑发送一个数据包,这个数据包会包含接收者的 IP地址,对方收到这个数据之后,会取出 IP地址 与自身的对比,相同则会把自己的 MAC地址 回复给对方,否则就丢弃这个数据包,这样计算机A就知道计算机B的 MAC地址

可能大家会问,知道了 MAC地址 后,发送数据是通过广播的形式发送,询问对方的 MAC地址 也是通过广播的形式来发送,那其他计算机怎么知道你是要传输数据还是询问 MAC地址 呢?

其实在询问 MAC地址 的数据包里,在对方的 MAC地址 这儿填的是一个特殊的 MAC地址 ,其他计算机看到这个特殊的 MAC地址 后,就知道广播是在询问了

如果两台计算机的 IP 不是处于同一个子网之中,这个时候我们就会把数据包发送给网关,然后让网关帮我们进行转发

运输层

通过 物理层 / 数据链路层 以及 网络层 的互相协调,我们成功的把数据从计算机A传到了计算机B,可是计算机B里面有各式各样的应用程序,计算机是如何知道这个数据是发给哪个应用程序的呢?

这个时候,端口 就上场了,当计算机A传输给计算机B的时候,还得指定一个端口,以供特定的应用程序来接收处理,作为程序员的我们对端口就更熟悉了,端口范围:0~65535,其中前1023个端口被系统占用

那么也就是说,传输层的功能就是建立端口到端口的通信,而相比之下网络层的功能是建立主机到主机的通信

有了 IP端口 ,我们才能准确通信,我们输入的IP有些并没有指定端口号,其实是有些传输协议,设定了一些默认端口,例如 HTTP 默认是80,HTTPS 默认是443,这些端口信息也会包含在数据包里面

传输层最常见了两大协议就是 TCP协议UDP协议

UDP协议

UDP协议 全称是用户数据报协议,是一种无连接的协议,与TCP协议一样用于处理数据包

UDP数据包分 标头 (8个字节) 和 数据 (加标头不超过65535个字节), UDP数据包放在IP数据包的 数据 中,标头主要包括发出端口和接收端口

UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的

UDP协议特点

  • 面向无连接

    • UDP 想发数据就可以开始发送了,不需要连接,它只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作
    • 在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了
    • 在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作
  • 有单播、多播、广播

    • UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能
  • 面向报文

    • 发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层
    • UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界
    • 因此,应用程序必须选择合适大小的报文
  • 不可靠性

    • 不可靠性首先体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠
    • 收到什么数据就传什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了
    • 网络环境时好时坏,但 UDP 没有拥塞控制,一直会以恒定的速度发送数据,即使网络条件不好,也不会对发送速率进行调整,这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景 ( 比如电话会议 ) 就需要使用 UDP 而不是 TCP
  • 头部开销小,传输数据报文高效

    • UDP 头部包含了以下几个数据
      • 两个十六位的端口号,分别为发出端口和接收端口
      • 整个数据报文的长度
      • 整个数据报文的检验和(IPv4 可选字段),该字段用于发现头部信息和数据中的错误
    • 所以UDP 的头部开销小,只有8字节,相比 TCP 的至少20字节要少得多,在传输数据报文时是很高效的

TCP协议

当一台计算机想要与另一台计算机通讯时,两台计算机之间的通信需要畅通且可靠,这样才能保证正确收发数据

  • 例如你想查看网页或查看电子邮件时,希望完整且按顺序查看网页,而不丢失任何内容

  • 又例如当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分

如果数据丢失或乱序,都不是你希望得到的结果,于是就用到了 TCP

TCP协议 全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 是面向连接的、可靠的流协议,什么是流?流就是指不间断的数据结构,可以把它想象成排水管中的水流

TCP三次握手建立连接,四次挥手断开连接又是一个话题,接下来我们就简单说一下

TCP三次握手

三次握手建立链接,为方便理解,仿一次电面

  • 小李 (客户端):您好,您是xx的面试官吗?

  • 面试官 (服务端):嗯嗯,是的,你是昨天投简历的小李吗?

  • 小李 (客户端):嗯嗯,是的,我是

接着,小李和面试官开始愉快的侃起了大山

根据上面的内容,我们再来看下图 (网图侵删)

tcpip3

按正规流程来说建立连接的三次握手如下

  • 第一次握手 客户端向服务端发送连接请求报文段,该报文段中包含自身的数据通讯初始序号,请求发送后,客户端便进入 SYN-SENT 状态
  • 第二次握手 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态
  • 第三次握手 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文,客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功

可能大家会有疑惑,为什么 TCP 建立连接需要三次握手,而不是两次?

其实这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误

TCP四次挥手

四次挥手断开链接,接着仿电面 😄

  • 面试官 (主动方):嗯,你的情况我这边了解了,等通知吧 ( 我想挂了 )

  • 小李 (被动方):嗯嗯,好的 ( 这就想挂了?我还没侃够 )

  • 小李 (被动方):那希望有机会能和您一块共事 ( 拜拜吧您嘞 )

  • 面试官 (主动方):嘀...嘀...嘀...嘀

再看正经的过程图 (网图侵删)

tcpip4

TCP是双向的,所以在断开连接时两端都需要发送 FIN 和 ACK

  • 第一次挥手 若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求

  • 第二次挥手 B 收到连接释放请求后,会告诉应用层要释放 TCP 链接,然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明 A 到 B 的连接已经释放,不再接收 A 发的数据了,但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A

  • 第三次挥手 B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态

  • 第四次挥手 A 收到释放请求后,向 B 发送确认应答,此时 A 进入TIME-WAIT 状态,该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃)时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态,当 B 收到确认应答后,也便进入 CLOSED 状态

为何客户端最后还等待2MSL

客户端需要保证最后一次发送的 ACK 报文到服务器,如果服务器未收到,可以请求客户端重发,这样客户端还有时间再发,重启 2MSL 计时

TCP/IP的并发限制

其实浏览器对同一域名下并发的 TCP 连接是有限制的(2-10个不等)

而且在 HTTP1.0 中往往一个资源下载就需要对应一个 TCP/IP 请求

TCP协议特点

  • 面向连接

    • 面向连接,是指发送数据之前必须在两端建立连接,建立连接的方法就是 三次握手,这样能建立可靠的连接,为数据的可靠传输打下了基础
  • 仅支持单播传输

    • 每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式
  • 面向字节流

    • TCP不像UDP一样那样一个个报文独立传输,而是在不保留报文边界的情况下以字节流方式进行传输
  • 可靠传输

    • 对于可靠传输,判断丢包,误码靠的是TCP的段编号以及确认号,TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收
    • 然后接收端实体对已成功收到的字节发回一个相应的确认(ACK),如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传
  • 提供拥塞控制

    • 当网络出现拥塞的时候,TCP 能够减小向网络注入数据的速率和数量,缓解拥塞
  • TCP提供全双工通信

    • TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据
    • 当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)

UDP协议和TCP协议区别

到了现在,大家应该对UDP和TCP都有些了解了,我们直接对比其作用再进行总结

对比 UDP TCP
是否连接 无连接 面向连接
是否可靠 不可靠传输,不使用流量控制和拥塞控制 可靠传输,使用流量控制和拥塞控制
连接个数 支持一对一,一对多,多对一和多对多通信 只能一对一通信
传输方式 面向报文 面向字节流
首部开销 首部开销小,仅8字节 首部最小20字节,最大60字节
适用场景 适用于实时应用 ( IP电话、视频会议、直播等 ) 适用于要求可靠传输的应用,例如文件传输
  • TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务
  • 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为
  • 对数据准确性要求高,速度可以相对较慢的,可以选用 TCP

TCP 我们就简单说到这里,接下来我们接着来看应用层

应用层

应用层是最接触用户的,上面几层我们收到了传输层收到的数据,TCP/UDP协议可以传递各种程序的数据包,就像邮箱/网页/FTP等等,所以就需要不同的协议来规定数据的格式,收到后才能渲染解读,应用层就是由这些协议构成,它的数据包放在UDP包/TCP包的 数据

我们遨游网络时经常用到的 HTTP 协议、文件传输用的 FTP 协议、电子邮件发送的 SMTP、域名解析的 DNS 协议、远程登录的 Telnet 协议等等都是属于应用层的

还有Socket,它是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作封装成几个简单的接口供应用层调用,从而实现进程在网络中的通信

上面我们已经基本了解到了计算机的一些通信基础,可以说到目前为止从一个IP到通信结束都已经知道了,但是我们输入的是域名不是IP,那么它是怎么变成IP通信的呢?这就要详细说说 DNS

DNS是什么

Domain Name System 简写 DNS ,翻译过来就是域名系统的意思,它是一种组织成域层次结构的计算机和网络服务命名系统,用于 TCP/IP 网络,作为将域名和IP地址相互映射的一个分布式数据库,它所提供的服务是用来将 主机名域名 转换为 IP地址 的工作

简单来说,IP地址 就像门牌号一样,我们在输入域名访问网站时,数据服务器是不认识你这个域名的,它只认识IP,你的域名会通过 DNS服务器 解析成IP值,通过这个门牌号 (IP值) 向数据服务器查找你的网站数据并给你返回到浏览器上

为什么需要DNS

上面我们说,网络通讯大部分是基于TCP/IP的,而TCP/IP是基于IP地址的,所以计算机在网络上进行通讯时只能识别如 252.94.131.12 之类的IP地址,而不能认识域名

我们没办法记住10个以上IP地址的网站 ( 你要说记性好那俺就乖乖闭嘴了😄 ),一般我们访问网站时,更多的是在浏览器地址栏中输入域名,就能看到所需要的页面,这是因为有一个叫 DNS服务器 的计算机自动把我们的域名 翻译 成了相应的IP地址,然后通过 IP地址 返回所对应的网页

域名结构

先来简单介绍下域名结构,有些前端同学可能不太了解,域名是在 Internet 上用于解决IP地址的一种方法,一个完整的域名由2个或2个以上的部分组成,各部分之间用英文的句号 . 来分隔

www.qq.com. 来说,等等,是不是多打了一个点,当然不是多打,这个最后的 . 代表的是根域名,默认情况下所有的网址的最后一位都是 .,只不过为了方便用户,通常都会省略,浏览器在 DNS解析 时会自动加上的,com是顶级域名,qq 是二级域名,www 是三级域名,如果 www 前还有,那就四级等等

那么我们在解析时的顺序就是

.  -> .com -> qq.com -> www.qq.com
复制代码

DNS获取流程

DNS是应用层协议,用于将用户提供的主机名解析为ip地址,它的获取流程大致分为下面这五步

  • 用户主机上运行着DNS客户端,就是我们的PC机或者手机客户端运行着DNS客户端

  • 浏览器将接收到的URL中抽取出域名字段,就是访问的主机名,例如 http://www.qq.com

  • DNS客户机端向DNS服务器端发送一份查询报文,报文中包含着要访问的主机名字段,中间还包括一些列缓存查询以及分布式DNS集群的工作

  • 该DNS客户机最终会收到一份回答报文,其中包含有该主机名对应的IP地址

  • 一旦该浏览器收到来自DNS的IP地址,就可以向该IP地址定位的HTTP服务器发起TCP连接

DNS解析过程

假如我们要访问 www.qq.com ,那么要经历什么呢,先来看一张图 ( 网图侵删 )

image-20200407141726887

先简单的瞄一眼这张图,看不懂也没关系,结合文字再看

上图主要分为三个段

  • DNS客户机,就是我们主机上运行的DNS客户端,PC机或者手机客户端都有
  • 客户机到服务器,这个服务器可以简单理解为我们当前所处网络环境的路由器
  • 服务器到服务器,最后这个服务器指的是 互联网服务提供商服务器/根域名服务器/顶级域名服务器/主域名服务器

DNS获取流程有很多步骤,这个过程中存在多个请求,如果每次都经过这么多步骤,那就太耗时间了,所以DNS有多级缓存的概念,接下来我们来简单描述下这个过程

  • 浏览器缓存

    • 当用户通过浏览器访问 www.qq.com 时,浏览器首先会在自己缓存中查找是否有该域名对应的IP地址
    • 若曾经访问过该域名且没有清空缓存便存在,不存在则继续下一步
  • 系统缓存

    • 当浏览器缓存中无域名对应IP则会自动检查用户计算机系统 Hosts 文件DNS缓存是否有该域名对应IP
  • 路由器缓存

    • 当浏览器及系统缓存中均无域名对应IP则进入路由器缓存中检查,以上三步均为客服端的DNS缓存
  • 互联网服务提供商 ( ISP ) DNS缓存

    • 当在用户客服端查找不到域名对应IP地址,则将进入互联网服务提供商 ( ISP ) DNS缓存中进行查询
    • 比如你用的是电信的网络,则会进入电信的DNS缓存服务器中进行查找
  • 根域名服务器

    • 当以上均未完成,则进入根服务器进行查询
    • 根域名服务器收到请求后会查看区域文件记录,若无则将其管辖范围内顶级域名 ( .com ) 服务器IP告诉本地DNS服务器
  • 顶级域名服务器

    • 顶级域名服务器收到请求后查看区域文件记录,若无则将其管辖范围内主域名( qq.com )服务器的IP地址告诉本地DNS服务器
  • 主域名服务器

    • 主域名服务器接受到请求后查询自己的缓存,如果没有则进入下一级域名服务器( www.qq.com )进行查找,并重复该步骤直至找到正确纪录
  • 保存结果至缓存

    • 本地域名服务器把返回的结果保存到缓存,以备下一次使用,同时将该结果反馈给客户端,客户端通过这个IP地址与Web服务器建立链接

DNS客户机可通过从以前查询获得的缓存信息就地应答查询,DNS服务器可使用其自身的资源记录信息缓存来应答查询,也可代表请求客户机来查询或联系其他DNS 服务器,以完全解析该名称,并随后将应答返回至客户机,这个过程称为 递归查询

客户机自己尝试联系其他的 DNS服务器来解析名称,如果客户机这么做,它会使用基于服务器应答的独立和附加的查询,该过程称作迭代,即DNS服务器之间的交互查询就是 迭代查询

这就是DNS的整个过程了,是这道面试题的第一步,面试官可能还会问DNS解析要怎么优化,不急,慢慢来

为什么要优化DNS解析

用户打开网站的整个流程中,DNS解析是第一环,当用户输入域名并敲回车后,系统调用 DNS客户端,寻找到用户配置或者自动分配的DNS IP,之后就开始整个解析过程,DNS服务器 完成解析到此域名的 数字IP服务器,一般情况下返回给定域名对应的IP地址会花费 20~120毫秒 的时间,而且在这个过程中浏览器什么都不会做直到DNS查询完毕

一旦解析完成,连接建立并保持,也就是顺利的访问以后,网页以后的下载速度就和DNS没关系了,直到下一次重新解析和发起访问请求

很多小型网站,DNS解析时间都接近 0.5s,有些甚至需要 1s 左右才可以解析出结果,一般网站用户的等待时间超过 8s 就会放弃访问,而对于电子商务网站,4s 就是用户忍耐极限,而一般经过优化的小型网站,DNS解析时间都可以控制在 200ms 左右,而带宽在 100M 左右的网站,经过优化,DNS解析时间可以控制在 50~100ms

那么,你现在知道为什么要优化DNS解析了吧,怎么优化呢?我们接着看

DNS解析优化-善用缓存之TTL

上买我们也看了,DNS存在着多级缓存,每次找这么多级,很定耗时间,我们要尽量多的让用户直接从运营商的DNS缓存中拿到解析记录,这样就不需要走根域名服务器以下的这些过程,自然就节省了一些时间

我们购买域名做域名解析时,有一个 TTL 值 ( 如下图阿里云域名解析中所示 )

image-20200407201056309

它指的是域名解析的生命周期 ( 秒为单位 ),简单来说它表示DNS服务器解析域名时记录在DNS服务器上的缓存时间,这个值的大小设置也是很有学问的,我们要在尽可能快的情况下又要保证当服务器出问题时能够尽快切换

  • 大家自己肯定清楚自己的服务器有没有多台或备份,若无备份,那服务器宕机时只能生抗,所以,TTL 时间对于你来说是越长越好,因为 TTL 短的目的是服务器发生问题时,可以及时切换,这个对于没有备份的网站基本利用不上,所以这时你的 TTL 设置就越长越好,当然了,也不能太长,一般设置 TTL 3600 即可
  • 若有备份或多台服务器,会发生由于服务器宕机需要及时做切换,TTL 时间越短切换越及时,但是 TTL 时间越短,也就意味着运营商DNS经常缓存不住,一般用户,设置为 TTL 600 即可,如果对及时切换,要求特别苛刻的网站,设置 TTL 120 就行

DNS解析优化-负载均衡

在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的,可以根据每台机器的负载量或该机器离用户地理位置的距离入手

就像我们使用CDN厂商做域名解析,它也是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容,CDN厂商的域名解析服务器用户量多被访问的次数也多,域名解析服务器的A记录基本上会被各地运营商的DNS一直缓存着,所以服务效果也是最好的

HTTP & HTTPS

说完DNS,本来还想写段HTTP和HTTPS,这块也能说好久,但是后来又感觉写在这有些不太合适,那就下次有机会单独写吧

感悟

网络通信篇到此结束,虽然此文写了上万字,但只能说整合了内容讲了个大概,怎么说呢,网络通信相关的一些知识都有提到,但并未深入,所以面试前临阵磨枪或查漏补缺可以,不要妄想通过看此文或者某一篇帖子就认为自己懂了网络通信,TCP/IP/DNS/HTTP/HTTPS这些内容随便挑出来一个都可以长篇大论

当然,和大多数帖子一样,此文庞观的为大家梳理了一下网络通信的内容,并用通俗易懂的语气为大家描述,这也是为了大多数非科班出身的小伙伴,有错误的地方望海涵也望提出

如果大家想进一步了解网络通信,也可以此文为引子,深入看一些相关知识,第三文总结也为大家整理出来了网络和浏览器方面知识的思维导图,哪里不会自己去查资料找答案即可

下一文「一道面试题」输入URL到渲染全面梳理中-页面渲染篇,待续哦。。

哦,还有,可以加个好友加下群一起交流噻,公众号【不正经的前端】也欢迎关注呦 😄