Connection management in HTTP 1.x
HTTP 1.x中的连接管理
连接管理是HTTP中的一个关键主题:打开和维护连接主要影响Web站点和Web应用程序的性能。在HTTP / 1.x中,有几种模式:短暂连接
,持久连接
和HTTP流水线。
HTTP主要依赖于TCP的传输协议,在客户端和服务器之间提供连接。在初期,HTTP使用单一模型来处理这种连接。这些连接是短暂的:每次请求需要发送时创建一个新连接,并在收到答复后关闭。
这个简单的模型对性能有着天生的限制:打开每个TCP连接是耗费资源的操作。必须在客户端和服务器之间交换几条消息。当请求需要发送时,网络延迟和带宽会影响性能。现代网页需要许多请求(十几个或更多)来提供所需的信息量,证明这种早期模型效率低下。
HTTP / 1.1中创建了两个较新的模型。持久连接模型保持连续请求之间的连接打开,减少打开新连接所需的时间。HTTP流水线模型更进一步,通过发送几个连续的请求,甚至不用等待答案,减少了网络中的大部分延迟。
HTTP / 2添加了用于连接管理的其他模型。
需要注意的一点是,HTTP中的连接管理适用于两个连续节点之间的连接,即逐跳而不是端到端。用于客户端与其第一个代理之间连接的模型可能与代理与目标服务器(或任何中间代理)之间的模型不同。参与定义的连接模型,如HTTP标头Connection
和Keep-Alive
,是逐跳头与他们的价值观能够通过中间节点进行更改。
一个相关的主题是HTTP连接升级的概念,其中HTTP / 1.1连接升级为不同的协议,例如TLS / 1.0,WebSocket甚至HTTP / 2的明文。此协议升级机制在其他地方有更详细的记录。
短暂的连接
HTTP的原始模型和HTTP / 1.0中的默认模型是短暂的连接
。每个HTTP请求都在其自己的连接上完成; 这意味着TCP握手在每个HTTP请求之前发生,并且这些都是序列化的。
TCP握手本身非常耗时,但TCP连接适应其负载,在连接更持久(或温暖)的情况下变得更高效。短暂的连接不利用TCP的这种效率特性,并且通过坚持通过新的冷连接进行传输而使性能从最佳状态下降。
该模型是HTTP / 1.0中使用的默认模型(如果没有Connection
标题或者其值设置为close
)。在HTTP / 1.1中,这个模型只有在Connection
头文件的值为close
。
除非处理一个不支持持续连接的非常旧的系统,否则没有令人信服的理由来使用此模型。
持续连接
短暂连接有两个主要问题:建立新连接所花费的时间非常长,并且只有在此连接已使用一段时间(热连接)时,底层TCP连接的性能才会更好。为了缓解这些问题,设计了持久连接
的概念,甚至在HTTP / 1.1之前。或者,这可以被称为保持连接
。
持续连接是一段时间内保持打开的状态,可以重复使用多个请求,从而节省了对新的TCP握手的需求,并利用TCP的性能增强功能。此连接不会永远保持打开状态:闲置连接在一段时间后关闭(服务器可能会使用Keep-Alive
标题指定连接应保持打开的最短时间)。
持续连接也有缺点; 即使在闲置时也会占用服务器资源,并且在高负载下可以执行DoS攻击。在这种情况下,使用非持久连接,一旦空闲就关闭,可以提供更好的性能。
HTTP / 1.0连接默认情况下不持久。通常设置Connection
为其他任何东西都会使它们持久。closeretry-after
在HTTP / 1.1中,持久性是默认的,并且不再需要头(但它通常被添加为防止需要回退到HTTP / 1.0的情况的防御措施)。
HTTP流水线
在现代浏览器中,缺省情况下HTTP流水线不会被激活:
- Buggy 代理仍然很常见,并且这些会导致Web开发人员无法轻易预见和诊断的奇怪且不稳定的行为。
- 流水线执行起来很复杂:正在传输的资源的大小,将要使用的有效RTT以及有效带宽,都直接影响到流水线提供的改进。如果不知道这些,重要的信息可能会被拖延到不重要的信息后面。重要的概念甚至在页面布局中发展!因此,HTTP流水线在大多数情况下只会带来一些改进。
- 流水线服从HOL问题。
由于这些原因,流水线已经被HTTP / 2使用的更好的算法 - 多路复用
所取代。
默认情况下,HTTP请求按顺序发出。下一个请求只有在收到对当前请求的响应后才会发出。由于它们受到网络延迟和带宽限制的影响,因此在服务器看到
下一个请求之前,可能会导致严重的延迟。
流水线是通过相同的持续连接发送连续请求而不等待答案的过程,这避免了连接的延迟。从理论上讲,如果将两个HTTP请求打包到同一个TCP消息中,性能也可以提高。典型的MSS(最大段大小)大到足以包含几个简单的请求,尽管HTTP请求的大小需求会持续增长。
并非所有类型的HTTP请求可以为流水线:而仅仅是幂等方法,即GET
,HEAD
,PUT
和DELETE
,可以安全地重播:管道的内容应该在故障发生时可以简单地重复。
今天,每个HTTP / 1.1兼容的代理和服务器应该支持流水线操作,尽管许多实践中有一些限制:一个重要的原因是没有现代浏览器在默认情况下激活此功能。
域分片
除非你有一个非常具体的直接需求,否则不要使用这个弃用的技术; 改为切换到HTTP / 2。在HTTP / 2中,域分片不再有用:HTTP / 2连接能够非常好地处理并行未重要的请求。域分片甚至对性能不利。大多数HTTP / 2实现使用称为连接合并的技术来恢复最终的域分片。
由于HTTP / 1.x连接正在序列化请求,即使没有任何排序,如果没有足够的可用带宽,它也不会是最佳的。作为一种解决方案,浏览器打开几个连接到每个域,发送并行请求。默认情况下是2到3次连接,但现在已经增加到更常见的6个并行连接。如果尝试超过这个数字,可能会在服务器端触发DoS保护。
如果服务器希望获得更快的网站或应用程序响应,则服务器可能会强制打开更多连接。例如,而不必在同一域中的所有资源,比如说www.example.com
,它可以拆分成几个域www1.example.com
,www2.example.com
,www3.example.com
。每个域都解析为同一台
服务器,Web浏览器将打开6个连接(在我们的示例中,将连接提升到18)。这种技术被称为域分片
。
结论
改进的连接管理可以显着提高HTTP的性能。使用HTTP / 1.1或HTTP / 1.0与持久连接 - 至少在其变为空闲状态之前 - 因为这样可以获得最佳性能。然而,流水线的失败已经导致设计出优秀的连接管理模型,这些模型已经被合并到HTTP / 2中。