Web 客户端经常会打开到同一个站点的连接。比如,一个 Web 页面上的大部分内嵌图片通常都是来自同一个 Web 站点,而且相当一部分指向其他对象的超链接通常都指向同一个站点。因此,初始化了对某服务器 HTTP 请求的应用程序很可能会在不久的将来对那台服务器发起更多的请求。这种性质被称为站点本地性(site locality)。
因此,HTTP/1.1(以及 HTTP/1.0 的各种增强版本)允许 HTTP 设备在事务处理结束之后将 TCP 连接保持在打开状态,以便为未来的 HTTP 请求重用现在的连接。在事务处理结束之后仍然保持在打开状态的 TCP 连接被称为持久连接。非持久连接会在每个事务结束之后关闭。持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。
重用已对目标服务器打开的空闲持久连接,可以避开缓慢的连接建立阶段。
持久连接有两种类型:比较老的 HTTP/1.0+ "keep-alive" 连接,以及 HTTP/1.1 "persistent" 连接。
HTTP/1.0+ keep-alive 连接
Keep-Alive 操作
实现 HTTP/1.0 keep-alive 连接的客户端可以通过包含 Connection: Keep-Alive 首部请求将一条连接保持在打开状态。
如果服务器愿意为下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有 Connection: Keep-Alive 首部,客户端就认为服务器不支持 keep-alive,会在发回响应报文之后关闭连接。
Keep-Alive 选项
Keep-Alive 首部只是请求将连接保持在活跃状态。发出 keep-alive 请求之后,客户端和服务器并不一定会同意进行 keep-alive 会话。它们可以再任意时刻关闭空闲的 keep-alive 连接,并可随意限制 keep-alive 连接所处理事务的数量。
可以用 Keep-Alive 通用首部中指定的、由逗号分隔的选项来调节 keep-alive 的行为。
参数 timeout 是在 Keep-Alive 响应首部发送的。它估计了服务器希望将连接保持在活跃状态的时间。这并不是一个承若值。
参数 max 是在 Keep-Alive 响应首部发送的。它估计了服务器还希望为多少个事务保持此连接的活跃状态。这不是一个承若值。
Keep-Alive 首部还可支持任意未经处理的属性,这些属性主要用于诊断和调试。语法为 name [=value]。
Keep-Alive首部完全是可选的,但只有在提供 Connection: Keep-Alive 时才能使用它。这里有个 Keep-Alive 响应首部的例子,这个例子说明服务器最多还会为另外 5 个事务保持连接的打开状态,或者将打开状态保持到连接空闲了 2 分钟之后。
Connection: Keep-Alive
Keep-Alive: max=5, timeout=120
HTTP/1.1 持久连接
与 HTTP/1.0+ 的 keep-alive 连接不同, HTTP/1.1 持久连接在默认情况是激活的。除非特别指明,否则 HTTP/1.1 假定所有连接都是持久的。要在事务处理结束之后将连接关闭,HTTP/1.1 应用程序必须向报文中显示地添加一个 Connection: close 首部。这是与之前的 HTTP 协议版本有很重要的区别,在之前的版本中,keep-alive 连接要么是可选的,要么就是不支持的。
HTTP/1.1 客户端假定在收到响应后,除非响应中包含了 Connection: close 首部,不然 HTTP/1.1 连接就仍维持在打开状态。但是,客户端和服务器仍然可以随意关闭空闲的连接。不发送 Connection: close 并不意味着服务器承若永远将连接保持在打开状态。