TCP 和 HTTP 请求的关系

理解 TCP 连接与 HTTP 请求的复用机制,以及浏览器的并发处理方式

问题

TCP 连接和 HTTP 请求是什么关系?一个 TCP 连接可以发送多少个 HTTP 请求?这些请求能否并行处理?

解答

TCP 连接是否会在 HTTP 请求后立即断开

在 HTTP/1.0 时代,默认情况下每个 HTTP 请求完成后都会断开 TCP 连接,除非手动设置 Connection: keep-alive

从 HTTP/1.1 开始,Connection 默认为 keep-alive,TCP 连接会被复用。连接会在超时时间内保持打开状态,只有在超时后仍未被使用时才会主动断开。

一个 TCP 连接可以发送多少个 HTTP 请求

只要 TCP 连接没有断开,就可以持续发送多个 HTTP 请求,没有数量限制。

HTTP 请求能否在同一个 TCP 连接中并行处理

HTTP/1.1 的限制:

在 HTTP/1.1 中,单个 TCP 连接在同一时刻只能处理一个请求。任意两个 HTTP 请求从开始到结束的时间不能重叠。

虽然 HTTP/1.1 规范中定义了 Pipelining(管道化)来解决这个问题,但浏览器默认关闭了这个功能,原因包括:

  • 部分代理服务器无法正确处理 HTTP Pipelining
  • 正确实现流水线机制较为复杂
  • 存在 Head-of-line Blocking(队头阻塞)问题:如果第一个请求处理时间过长,后续所有请求都必须等待

HTTP/2 的改进:

HTTP/2 提供了 Multiplexing(多路复用)功能,可以在一个 TCP 连接中同时发起和响应多个 HTTP 请求,彻底解决了队头阻塞问题。

浏览器如何实现并发请求

虽然单个 TCP 连接在 HTTP/1.1 中无法并行处理请求,但浏览器会同时与服务器建立多个 TCP 连接来支持并发。

例如,Chrome 浏览器最多允许对同一个域名建立 6 个 TCP 连接,不同浏览器的限制有所差异。

HTTPS 和 HTTP/2 的情况

如果资源使用 HTTPS 连接且在同一域名下,浏览器会优先协商使用 HTTP/2 的 Multiplexing 功能进行多路传输。但并非所有资源都会使用同一个 TCP 连接。

如果无法使用 HTTP/2(HTTP/2 基于 HTTPS 实现),浏览器会在同一个域名下建立多个 TCP 连接,每个连接按顺序请求资源。

关键点

  • HTTP/1.1 默认开启 keep-alive,TCP 连接会被复用而不是每次请求后断开
  • HTTP/1.1 中单个 TCP 连接同一时刻只能处理一个请求,存在队头阻塞问题
  • HTTP/2 通过多路复用实现了在一个 TCP 连接中并行处理多个请求
  • 浏览器通过建立多个 TCP 连接(如 Chrome 的 6 个)来实现 HTTP/1.1 的并发请求
  • HTTPS 环境下优先使用 HTTP/2 的多路复用,否则回退到多连接模式