一个web页面上的大部分内嵌图片通常都来自一个Web站点,而且其他对象的超链接都指向同一个站点。因此,初始化对某服务器(这个站点)HTTP请求的应用程序可能会在不久的将来,对这台服务器发起更多的请求。这种属性被称为站点局部性。
因此,HTTP1.1(HTTP1.0增加版本)允许HTTP设备在事务处理结束(下图中有四个事务)之后,将TCP连接保持打开的状态,以便为未来的HTTP请求重用现在的连接。
在事务处理结束之后仍保持打开状态的TCP连接叫持久连接,非持久连接会在每个事务结束之后关闭。持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。
重用已对目标服务器打开的空闲持久连接,就可以避免缓慢的连接建立阶段。而已,已经打开的连接可以避免慢启动的拥塞和和适应阶段,以便更快地进行数据传输。
并行连接的缺点
- 每个事务都会打开/关闭一个新的连接,会耗费时间和带宽。
- 由于TCP慢启动特性的存在,每条新连接的性能都会有所降低。
- 可打开的并行连接数据实际上是有限的。
持久连接比并行连接更好的地方。持久连接降低了时延和连接建立的开销,将连接保持在调谐状态,而且减少了打开连接的潜在数量。但持久连接的没管理得当,会累积出大量的空闲连接,耗费本地以及远程客户端和服务器上的资源。现在,好多Web应用程序都会打开少量的并行连接,其中每个都是持久连接。
持久连接类型
- 比较老的HTTP/1.0+ Keep-alive
- HTTP1.1 Presistent
HTTP/1.0+ Keep-alive连接
大约从1996年开始,很多支持HTTP/1.0浏览器和服务器进行扩展,以支持一种称为Keep-alive的持久连接(实验性)。这些早期的持久连接存在操作性设计方面的缺陷,在HTTP/1.1中得以修正,但很多客户端和服务器仍使用早期的Keep-alive连接。
下面中显示持久连接与串行连接的性能优点,由于去除了连接和关闭连接的开销,所以时间线辰所缩减。也去掉慢启动阶段。Keep-alive操作
Keep-alive已经不再使用了,在当前的HTTP/1.1规范中也没有对它的说明。但很多浏览器和服务器对Keep-alive握手的使用仍然相当广泛,因此,HTTP的实现者应用做好与之操作的准备。
实现HTTP/1.0+ Keep-alive连接的客户端,需要在请求报文中加入一条(Connection: Keep-alive)头部保持打开状态(见下图)。如果服务器愿意为下一条请求保持打开状态,会在响应报文中包含相同的头部。如果响应报文中没有这条头部,客户端就认为服务器不支持Keep-alive,会在发回(或不发回)响应报文之后,关闭连接。
Keep-alive选项
Keep-alive首部是请求将连接保持持久状态。发出有Keep-alive首部的报文之后,客户端或服务器不一定同意进行Keep-alive会话。即将双方同意,也可以在任意时刻关闭空闲的Keep-alive连接,并可随意限制Keep-alive连接所处理的事务的数量。
Keep-alive选项:
- Timeout:是在Keep-alive响应报文首部发送的,它估计了服务器希望将连接保持在活跃状态时间。这不是一个承诺值。
- Max:是在Keep-alive响应报文首部发送的,它估计了服务器还希望为多少个事务保持此连接的活跃状态。这不是一个承诺值。
-
name [=value]: Keep-alive首部也支持任意未处理的属性,这些属性主要用于诊断和调度
Keep-alive首部是可选的,只有在提供了Connection: Keep-alive时才能使用它。
下面代码显示这个服务器最多为另外5个事务保持连接的打开状态,或者将打开状态保持到连接空闲2分钟之后。
Connection; Keep-alive
Keep-alive: max=5, timeout=120
Keep-alive连接的限制和规则
- 在HTTP/1.0中,Keep-alive不是默认使用的,在客户端请求中必须发送一个Connection: Keep-alive首部来激活Keep-alive连接。
- 如果客户端的请求报文中没有Connection: Keep-alive,服务器会在这个请求之后,关闭这个连接。
- 如果服务器响应报文中没有Connection: Keep-alive,客户端会在这个响应之后,关闭这个连接。
- 保持持久连接的条件:报文实体的主体部分必须有正确的Content-Length。如果错误的Content-Length值,将是一件糟糕的事情,事务处理的另一端无法精确地检测出一条报文结束和另一条报文的开始。
-
重要:应该忽略所有来自HTTP/1.0设备的Connection首部字段,因为它们可能是由比较老的代理服务器误转发的。如果不忽略的话,会产生哑代理问题。
在检测到HTTP/1.0协议,并有Connection首部字段时,代理和网关必须在将报文转发出去或将其缓存之前,删除在Connection首部中命名的所有的首部字段,以及Connection本身(在服务器端也可以做限制)。