DNS 解析过程
HTTP请求过程
-
DNS 域名解析 -->
-
发起 TCP 的 3 次握手 -->
-
1) Client首先发送一个连接试探,ACK=0 表示确认号无效,SYN = 1 表示这是一个连接请求或连接接受报文,同时表示这个数据报不能携带数据,seq = x 表示Client自己的初始序号(seq = 0 就代表这是第0号包),这时候Client进入syn_sent状态,表示客户端等待服务器的回复
-
2) Server监听到连接请求报文后,如同意建立连接,则向Client发送确认。TCP报文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到对方下一个报文段的第一个数据字节序号是x+1,同时表明x为止的所有数据都已正确收到(ack=1其实是ack=0+1,也就是期望客户端的第1个包),seq = y 表示Server 自己的初始序号(seq=0就代表这是服务器这边发出的第0号包)。这时服务器进入syn_rcvd,表示服务器已经收到Client的连接请求,等待client的确认。
-
3) Client收到确认后还需再次发送确认,同时携带要发送给Server的数据。ACK 置1 表示确认号ack= y + 1 有效(代表期望收到服务器的第1个包),Client自己的序号seq= x + 1(表示这就是我的第1个包,相对于第0个包来说的),一旦收到Client的确认之后,这个TCP连接就进入Established状态,就可以发起http请求了。
-
TCP 为什么需要3次握手?
举个例子:
假设一个老外在故宫里面迷路了,看到了小明,于是就有下面的对话:
老外: Excuse me,Can you Speak English?
小明: yes 。
老外: OK,I want ...
在问路之前,老外先问小明是否会说英语,小明回答是的,这时老外才开始问路2个计算机通信是靠协议(目前流行的TCP/IP协议)来实现,如果2个计算机使用的协议不一样,那是不能进行通信的,所以这个3次握手就相当于试探一下对方是否遵循TCP/IP协议,协商完成后就可以进行通信了,当然这样理解不是那么准确。
为什么HTTP协议要基于TCP来实现?
目前在Internet中所有的传输都是通过TCP/IP进行的,HTTP协议作为TCP/IP模型中应用层的协议也不例外,TCP是一个端到端的可靠的面向连接的协议,所以HTTP基于传输层TCP协议不用担心数据的传输的各种问题。
-
-
建立 TCP 连接后发起 http 请求 -->
-
服务器响应 http 请求, 浏览器得到html代码
-
浏览器解析html代码,并请求html代码中的资源
浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里的顺序,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源
浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到 现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。 -
浏览器对页面进行渲染呈现给用户
- 渲染引擎 (Webkit Blink Gecko Trident Presto)
- JavaScript引擎(V8)
DNS解析
-
Step1: 首先拿到 URL 后,浏览器会寻找本地的 DNS 缓存,看看是否有对应的 IP 地址
- 如果缓存中存在那就好了, 直接向该IP地址发送
- 如果没有,那就得向 DNS Server 发送一个请求,找到你想要的 IP 地址。
-
Step2: 首先他会向你的 ISP(互联网服务提供商) 相关的 DNS servers 发送 DNS query。然后这些 DNS 进行递归查询(recursive)。所谓的递归查询,就是能够直接返回对应的IP地址,而不是其他的 DNS server 地址。
-
Step3: 如果上述的 DNS Servers 没有你要的域名地址,则就会发送迭代查询,即会先从 root nameservers 找起。 即是假如你要查询 www.example.com ,会先从包含根结点的 13 台最高级域名服务器开始。
-
Step4: 接着,以从右向左的方式递进,找到 com. 然后向包含 com 的 TLD(顶级域名) nameservers 发送 DNS 请求。接着找到包含 example 的 DNS server。
-
Step5: 现在进入到了example.com 部分,即是现在正在询问的是权威服务器,该服务器里面包含了你想要的域名信息,也就是拿到了最后的结果 record 。
-
Step6: 递归查询的 DNS Server 接受到这 record 之后, 会将该record 保存一份到本地。 如果下一次你再请求这个 domain 时,我就可以直接返回给你了。由于每条记录都会存在 TLL ,所以 server 每隔一段时间都会发送一次请求,获取新的 record,
-
Step7: 最后,再经由最近的 DNS Server 将该条 record 返回。 同样,你的设备也会存一份该 record 的副本。 之后,就是 TCP 的事了,下面是一张萌萌的简化图:
迭代查询的流程
流程: . => com. => .exampl.com. => www.example.com. => IP adress
DNS PC和Mobile 域名发散和收敛
-
在 PC 上,我们采用域名发散策略,是因为在 PC 端上,DNS 解析通常而言只需要几十 ms ,可以接受。
-
而移动端,2G 网络,3G网络,4G网络/wifi 强网,而且移动 4G 容易在信号不理想的地段降级成 2G ,通过大量的数据采集和真实网络抓包分析(存在DNS解析的请求),DNS的消耗相当可观,2G网络大量5-10s,3G网络平均也要3-5s(数据来源于淘宝)。 下面附上在 2G,3G,4G, WIFI 情况下 DNS 递归解析的时间 (ms):
QQ截图20160408104038 -
因为在增加域的同时,往往会给浏览器带来 DNS 解析的开销。所以在这种情况下,提出了域名收敛,减少域名数量可以降低 DNS 解析的成本。
-
在 2 个域名分散条件下,网页的加载速度提升较大,而第 3 个以后就比较慢了。 所以,一般来说,域名分散的数量最好在 3 以下。