1.4 连接管理
这部分可以了解到:HTTP是如何使用TCP连接的,TCP的时延,瓶颈,障碍,HTTP的优化,包括并行连接,keep-alive和管道话连接等。
1.4.1 TCP连接
世界上几乎所有的HTTP通信都是由TCP/IP承载的。当浏览器收到一个URL时,回经过下图的步骤:
1.4.1.1 TCP的可靠数据管道
HTTP应用层的协议,依靠它的下一层传输层TCP协议进行连接。要想正确快速地发送数据,就要先了解一点TCP的知识。
TCP为HTTP连接了一条可靠的比特传输管道。从TCP连接一段填入的字节会从另一端以原来的顺序正确地传送出来。
1.4.1.2 TCP流分段的,IP分组传送
TCP的数据是通过IP数据报的小数据块发送的。
通常的层次为:
HTTP--------报文------------------------数据流
TCP----------TCP头+报文-------------单位是数据报
IP-------------IP头+TCP头+报文------单位是分组
TCP为俩台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。
1.4.1.3 保持TCP连接的正确运行
传输层TCP协议提供端到端的通信。TCP是通过端口号来保持这些连接正确运行的。IP地址可以将你连接到正确的计算机,而端口号则可以将你连接到正确的应用程序。
TCP连接通过4个值来识别:
<源IP地址、源端口号、目的IP地址、目的端口号>
这四个值唯一的定义了一条连接。
1.4.2 对TCP性能的考虑
理解TCP的某些基本性能特点之后,就能更好地了解HTTP的链接优化特性。
1.4.2.1 HTTP事务的延迟
HHTP时延的组成:
- 解析IP地址和端口号,主机名对应IP 地址的DNS解析
- 客户端向服务器发送一条TCP连接请求,连接的时延(服务器处理连接的实验)
- 连接建立之后的发送请求的传输时延
- 服务器对接收到的请求的处理时延
- web服务器回送HTTP响应的传输时延
这些TCP网络时延的大小取决于硬件速度,网络和服务器的负荷,请求和响应报文的尺寸,以及客户端和服务器之间的距离。
1.4.2.2 性能聚焦区域
下面是一些会对HTTP产生影响的,最常见的TCP相关时延,会在之后的小节中讲解:
- HTTP连接握手时延
- TCP慢启动
1.4.2.3 HTTP连接握手时延
握手:请求—接受请求----确认信息,连接成功
小的HTTP事务可能会在TCP建立上花费50%或者更多时间。所以在后面会讨论HTTP如何通过重用现存连接。来减小这种TCP建立时延所造成的影响。
1.4.2.4 TCP慢启动
TCP在连接过程的三次握手完成后,开始传数据,并不是一开始向网络通道中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞;而是根据初始的cwnd大小逐步增加发送的数据量,cwnd初始化为1个最大报文段(MSS)大小(这个值可配置不一定是1个MSS);每当有一个报文段被确认,cwnd大小指数增长。
开始 —> cwnd = 1
1个RTT后 —> cwnd = 21 = 2
2个RTT后 —> cwnd = 22= 4
3个RTT后 —> cwnd = 4*2 = 8
这种方式被称作“打开拥塞窗口”
所以新连接的传输速度会比已经交换过一定量数据的连接慢一些。要想传输得更快一点,就要考虑利用之前已经用过的连接,这就之后要讲的HTTPkeep-alive持久连接。
1.4.3 HTTP连接的处理
回到HTTP,下面是解释操作和优化连接的HTTP技术。
1.4.3.1 被误用的Connection首部
Connection
头(header) 决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive
”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成。
语法
Connection: keep-alive
onnection: close
close
:表明客户端或服务器想要关闭该网络连接,这是HTTP/1.0请求的默认值
以逗号分隔的HTTP头 [通常仅有 keep-alive]
表明客户端想要保持该网络连接打开,HTTP/1.1的请求默认使用一个持久连接。这个请求头列表由头部名组成,这些头将被第一个非透明的代理或者代理间的缓存所移除:这些头定义了发出者和第一个实体之间的连接,而不是和目的地节点间的连接。
1.4.3.2 串行事务处理时延
只对连接进行简单的管理,那TCP的性能时延可能或叠加起来。
比如有一个html文件和三个图片文件,每一个文件都要登上一个连接处理完之后重新开一条新连接,那连接时延和慢启动时延就会叠加起来。
加载一张图片时一张张加载而不是图片一起加载也会让人心里感觉很慢
还有就是有的浏览器在对象加载完毕之前无法获知对象的尺寸,它们可能需要尺寸信息来决定图放在哪个地方,所以在加载完所有资源时页面上并不会显示,用户就会对装载速度一无所知。
所以在后面讨论了四种提高HTTP性能的技术:
- 并行连接:
多条TCP连接
发起并发的HTTP请求 - 持久连接:
重用TCP连接
- 管道化连接:通过
共享的TCP连接
发起兵法的HTTP请求 - 复用的连接:
交替传送请求和响应报文
1.4.4 并行连接
HTTP允许客户端打开多条连接,并行执行多个HTTP事务。
但是并行连接不一定更快,因为HTTP事务可能会耗尽可用的带宽,并且大量连接会消耗很多内存资源。
实际上浏览器确实使用了并行连接,但它们会将并行连接的总数限制为较小的值(通常是4个)
1.4.5 持久连接
web客户端经常会打开到同一个站点,初始化了对某服务器HTTP请求的应用程序很可能会在不久的将来对那台服务器发起更多的请求,在同一个站点请求多个资源。这种性质被称为站点本地性
因此,HTTP/1.1允许HTTP设备在设备事务处理结束之后将TCP连接保持打开状态,以便为未来在不同事务重用
现存的连接.
在事务处理结束之后仍然保持打开状态的TCP连接被称为持久连接
持久连接降低了时延和连接建立的开销,但是如果管理不当,会积累出大量的空闲连接,消耗本地和服务器上的资源。
持久连接有两种类型:
keep-alive
:
Connection: Keep-Alive
可选参数:
timeout:估计了服务器希望将连接保持在活跃状态的时间
max:估计了服务器还希望为多少个事务保持连接的活跃状态
如:
Connection: Keep-Alive
Keep-Alive: max=5, timeout=120
注意:
-
keep-alive不是默认的,每条想要持久连接的链接都要讲首部写上,没有写上那链接就关闭
-
只有在无需检测连接的关闭就可以确定报文主体的结束的情况下下能将连接保持在打开状态。也就是说要有正确的Content-Length,有多不见媒体类型,或者用了分块传输编码,这样才能检测出来一条报文的结束和另一条报文的开始。
persistent
:
持久连接(persistent在默认情况下是激活状态的),除非特别指定,HTTP/1.1假定所有连接都是持久的。要在事务结束后关闭连接,必须加上Connection:close首部。
一个用户客户端最任何服务器或代理最多智能维护两条持久连接。
1.4.6 管道化连接
可以在持久连接上可选地使用管道连接。即:在响应到达之前,可以将多条请求放入队列。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能
使用限制:
- 必须在持久连接的基础上才可以使用管道化连接
- 必须按照与请求相同的顺序回送HTTP响应
- 不应该用管道化的方式发送会产生副作用的请求(如POST),出错的时候管道化方式会阻碍客户端了解服务器执行的是一系列管道化请求的哪一些。不好查错
1.4.7 关闭连接的奥秘
幂等
事务:一个事务,不管是执行一次还是很多次,得到的结果都相同,这个事务就是幂等的
客户端不应该以管道化方式传送非幂等请求(POST
)
关闭:
close():输入和输出信道都关闭,“完全关闭”
shutdown():单独关闭输入或者输出信道,“半关闭”
使用半关闭来防止对等实体收到非预期的写入错误。
关闭连接的输入信道比较危险(关闭输入了,缓存,未读,都读不了了)
关闭连接的输出信道总是很安全
实现正常更多关闭应该先关闭它的输出信道
,然后等待
连接另外一段的对等实体关闭它的输出信道。当两端都告诉对方不会在发送任何数据之后,连接就会被完全关闭
,而不会有重置的危险