连接管理是一个 HTTP 的关键话题:
打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。
在 HTTP/1.x 里有多种模型:短连接、长连接和 HTTP 流水线。
- HTTP 的传输协议主要依赖于 TCP 来提供从客户端到服务器端之间的连接。
- HTTP/1.1 之前,默认使用短链接。
- HTTP/1.1 新增两个模型:长连接和 HTTP 流水线。默认使用长连接。
短链接
短链接,每发起一个请求时都会创建一个新的 TCP 连接,并在收到应答时立即关闭。连接的生命周期短暂。
TCP 协议握手是一个耗费时间的过程,为了解决这一问题,TCP采用热连接来适应负载。但短连接破坏了 TCP 具备的能力,并且新的冷连接降低了其性能。
将 Connection 被设置为 close可以在 HTTP/1.1 中使用短链接。
长链接
客户端向服务端发送请求,创建的TCP链接不会立即关闭,可以重复发送一系列请求。连接在空闲一段时间后会被关闭,服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间。
HTTP/1.0 里默认并不使用长连接。把 Connection 设置成 close 以外的其他参数都可以让其保持长连接,通常会设置为 retry-after。
在 HTTP/1.1 里,默认就是长连接的,不再需要标头。
长链接缺点
- 在空闲状态,它还是会消耗服务器资源,而且在重负载时,还有可能遭受 DoS 攻击。
HTTP 流水线
默认情况下,HTTP 请求是按顺序发出的。下一个请求只有在当前请求收到响应过后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。
流水线是在同一条长连接上发出连续的请求,而不用等待应答返回。只有幂等方式,比如 GET、HEAD、PUT 和 DELETE 能够被安全地重试。如果有故障发生时,流水线的内容要能被轻易的重试。
- 优点
- 避免连接延迟
- 理论上讲,性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升
由于流水线使用起来比较复杂,并且现代浏览器并不是默认启用的,所以 HTTP/2 提供更好的算法 多路复用,用来取代流水线这种方式。
域名分片
HTTP/1.x 的连接,请求是序列化的,哪怕本来是无序的,在没有足够庞大可用的带宽时,也无从优化。
解决方案:
- 浏览器为每个域名建立多个连接,以实现并发请求。
- 曾经默认的连接数量为 2 到 3 个,现在比较常用的并发连接数已经增加到 6 条。
- 如果尝试大于这个数字,就有触发服务器 DoS 保护的风险。
如果服务器端想要更快速的响应网站或应用程序的应答,它可以迫使客户端建立更多的连接。例如,不要在同一个域名下获取所有资源,假设有个域名是 www.example.com,我们可以把它拆分成好几个域名:www1.example.com、www2.example.com、www3.example.com。所有这些域名都指向同一台服务器,浏览器会同时为每个域名建立 6 条连接(在我们这个例子中,连接数会达到 18 条)。这一技术被称作域名分片
HTTP/2 的连接可以很好的处理并发的无优先级的请求。大多数 HTTP/2 的实现还会使用一种称作连接聚合的技术去尝试合并被分片的域名。如果有域名分片的需求,可以使用 HTTP/2 替代。