分布式系统架构:技术栈详解与快速进阶
上QQ阅读APP看书,第一时间看更新

3.2.2 传输过程

互联网网络传输基于TCP协议传输,TCP三次握手过程,如图3-1所示。

058-1

图3-1 TCP三次握手交互图

注意,第1次SYN是请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1。ACK是确认号是否有效,一般置为1。

第一次握手:建立连接时,客户端发送SYN包(SYN=1)到服务器,并进入SYN_SENT状态,等待服务器确认。SYN是同步序列编号(Synchronize Sequence Number)。

第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(SYN=1),即SYN+ACK包,此时服务器进入SYN_RECV状态。

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

网络传输完毕后,客户端进程发出连接释放报文,并且停止发送数据。此时会经过TCP四次挥手,其过程如图3-2所示。

059-1

图3-2 TCP四次挥手交互图

注意,第1次FIN是希望断开连接,一般置FIN为1。挥手处理过程如下。

1)客户端进程发出连接释放报文,并且停止发送数据,释放数据报文首部,FIN=1,序列号为seq=u,TCP规定FIN报文段不携带数据也要消耗一个序号。

2)服务器接收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自身序列号seq=v,服务端进入CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端没有数据要发送,但是服务器若发送数据,客户端依然要接收。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

3)收到服务器的确认请求后,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接收服务器发送的最后的数据)。

4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于处于半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,那么服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6)服务器只要收到了客户端发出的确认信息,就会立即进入CLOSED状态,同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

互联网中Web请求过程如图3-3所示。

060-1

图3-3 Web请求过程图

注意,输入URL地址或点击URL链接后,浏览器打开呈现的请求过程具体分为以下步骤。

1)查找DNS,解析出与URL对应的IP地址(公网IP)。

2)初始化网络连接(包括TCP三次握手)。

3)发送HTTP请求。

4)通过网络传输请求到服务器。

5)Web服务器接收请求,经过处理转发到Web应用。

6)Web应用处理请求,如MVC框架,返回内容。

7)通过网络传输应答内容到前端浏览器。

8)浏览器解析从服务器返回的应答内容,并开始渲染和绘制。

9)根据HTML内容来构建DOM(文档对象模型)。

10)加载和解析样式,构建CSSOM(CSS对象模型)。

11)根据DOM和CSSOM来构建渲染树,按照文档顺序从上到下依次进行。

12)根据渲染树的过程,适当把已经构建好的部分绘制到界面上,中间会伴随着重绘和回流,循环操作,直到渲染绘制完成。

13)整个页面加载完成,触发OnLoad事件。

详细流程分析如下。

1)要通过URL将请求发送到服务器,浏览器就要知道这个URL对应的IP是什么,只有知道了IP地址,浏览器才能将请求发送到指定服务器的具体IP和端口。浏览器的DNS解析器负责把URL解析为正确的IP地址,这个解析很花时间,而且在解析过程中,浏览器不能从服务器那里下载任何东西。浏览器和操作系统提供了DNS解析缓存支持。

2)获取IP之后,浏览器会请求与服务器建立连接,TCP经过3次握手后建立连接通道。

3)浏览器真实发送HTTP请求,发送请求报文,包含请求行(包含请求方法、URI、HTTP版本信息;请求首部字段)、请求内容实体、空行。

  • 通用首部字段(请求报文与响应报文都会使用的首部字段)如下。
    • Date:创建报文时间。
    • Connection:连接的管理。
    • Cache-Control:缓存的控制。
    • Transfer-Encoding:报文主体的传输编码方式。
  • 请求首部字段(请求报文会使用的首部字段)如下。
    • Host:请求资源所在服务器。
    • Accept:可处理的媒体类型。
    • Accept-Charset:可接收的字符集。
    • Accept-Encoding:可接受的内容编码。
    • Accept-Language:可接受的自然语言。

4)网络开始传输请求到服务器,这个会包含很多时间,如网络阻塞时间、网络延迟时间、真正传输内容时间等。

5)Web服务器收到请求,会根据URL上下文转交给相应Web应用进行处理。

6)Web应用会进行很多处理,如filter、aop前置处理、IOC处理、创建对象,处理后会生成Response对象。熟悉Spring的读者对此过程会更清晰。

7)返回HTTP响应报文,包含状态行(包含HTTP版本、状态码、状态码的原因短语)、响应首部字段、响应内容实体、空行。

  • 响应首部字段(响应报文会使用的首部字段):
    • Accept-Ranges:可接收的字节范围。
    • Location:令客户端重新定向到的URI。
    • Server:HTTP服务器的安装信息。
  • 实体首部字段(请求报文与响应报文的实体部分使用的首部字段):
    • Allow:资源可支持的HTTP方法。
    • Content-Type:实体主类的类型。
    • Content-Encoding:实体主体适用的编码方式。
    • Content-Language:实体主体的自然语言。
    • Content-Length:实体主体的的字节数。
    • Content-Range:实体主体的位置范围,一般在发出部分请求时使用。

8)通过网络将应答内容传送回前端浏览器,先返回HTML代码,不包含图片、外部脚本、CSS等。

9)在浏览器解析页面进行渲染和绘制,具体过程如下:

a)装载和解析HTML文档,构建DOM,如果在解析过程中发现需要其他资源,如图片,浏览器会发出获取资源的请求;

b)装载和解析CSS,构建cssom;

c)根据DOM和cssom构建渲染树;

d)对渲染树节点进行布局处理,确认其屏幕位置;

e)将渲染好的节点绘制到界面上,渲染引擎不会等到所有HTML都解析完后才创建布局渲染树,而是在处理解析渲染树的同时向后端请求资源。