HTTP 反向代理是否通常在代理连接的客户端而不是在服务器端启用 HTTP Keep-Alive?

Los*_*ter 31 http nginx load-balancing haproxy sticky-sessions

HAProxy 能够在客户端(客户端 <-> HAProxy)启用 HTTP 保持活动,但在服务器端(HAProxy <-> 服务器)禁用它。

我们的一些客户通过卫星连接到我们的网络服务,因此延迟约为 600 毫秒,我认为通过启用保持活动,它会加快速度。我对吗?

这是 Nginx 支持的吗?这是其他软件和硬件负载平衡器中广泛实现的功能吗?除了HAProxy还有什么?

Tha*_*Guy 46

编辑:我的回答仅涵盖原始未经编辑的问题,即这种事情在负载均衡器/反向代理中是否是典型的。我不确定 nginx/product X 是否支持这个,我 99.9% 的反向代理经验是使用 HAproxy。

正确的。HTTP Keep-Alive 在客户端,但不在服务器端。

为什么?

如果您分解一些细节,您会很快明白为什么这是一个好处。在这个例子中,假设我们正在加载一个页面 www.example.com,该页面包含 3 张图片,img[1-3].jpg。

浏览器加载页面,没有 Keep-Alive

  1. 客户端在端口 80 上建立到 www.example.com 的 TCP 连接
  2. 客户端对“/”执行 HTTP GET 请求
  3. 服务器发送 URI "/" 的 HTML 内容(包括引用 3 个图像的 HTML 标签)
  4. 服务器关闭 TCP 连接
  5. 客户端在端口 80 上建立到 www.example.com 的 TCP 连接
  6. 客户端对“/img1.jpg”执行 HTTP GET 请求
  7. 服务器发送图像
  8. 服务器关闭 TCP 连接
  9. 客户端在端口 80 上建立到 www.example.com 的 TCP 连接
  10. 客户端对“/img2.jpg”执行 HTTP GET 请求
  11. 服务器发送图像
  12. 服务器关闭 TCP 连接
  13. 客户端在端口 80 上建立到 www.example.com 的 TCP 连接
  14. 客户端对“/img3.jpg”执行 HTTP GET 请求
  15. 服务器发送图像
  16. 服务器关闭 TCP 连接

请注意,有 4 个单独的 TCP 会话建立然后关闭。

浏览器加载页面,使用 Keep-Alive

HTTP Keep-Alive 允许单个 TCP 连接服务多个 HTTP 请求,一个接一个。

  1. 客户端在端口 80 上建立到 www.example.com 的 TCP 连接
  2. 客户端对“/”执行 HTTP GET 请求,并要求服务器使其成为 HTTP Keep-Alive 会话。
  3. 服务器发送 URI "/" 的 HTML 内容(包括引用 3 个图像的 HTML 标签)
  4. 服务器没有关闭TCP 连接
  5. 客户端对“/img1.jpg”进行 HTTP GET 请求
  6. 服务器发送图像
  7. 客户端对“/img2.jpg”进行 HTTP GET 请求
  8. 服务器发送图像
  9. 客户端对“/img3.jpg”进行 HTTP GET 请求
  10. 服务器发送图像
  11. 如果在其 HTTP Keep-Alive 超时期限内没有收到更多 HTTP 请求,则服务器关闭 TCP 连接

请注意,使用 Keep-Alive,仅建立 1 个 TCP 连接并最终关闭。

为什么 Keep-Alive 更好?

要回答这个问题,您必须了解在客户端和服务器之间建立 TCP 连接需要什么。这称为 TCP 3 次握手。

  1. 客户端发送一个 SYN(chronise) 数据包
  2. 服务器发回一个 SYN(chronise) ACK(nowledgement), SYN-ACK
  3. 客户端发送一个 ACK​​(nowledgement) 数据包
  4. 客户端和服务器现在都认为 TCP 连接处于活动状态

网络存在延迟,因此 3 次握手中的每一步都需要一定的时间。假设客户端和服务器之间有 30 毫秒,建立 TCP 连接所需的 IP 数据包的来回发送意味着建立 TCP 连接需要 3 x 30 毫秒 = 90 毫秒。

这听起来可能不多,但如果我们考虑到在我们原来的例子中,我们必须建立 4 个单独的 TCP 连接,这变成了 360 毫秒。如果客户端和服务器之间的延迟是 100 毫秒而不是 30 毫秒怎么办?然后我们的 4 个连接需要 1200 毫秒才能建立。

更糟糕的是,一个典型的网页可能需要远远不止 3 个图像才能加载,客户端可能需要请求多个 CSS、JavaScript、图像或其他文件。如果页面加载了 30 个其他文件并且客户端-服务器延迟为 100 毫秒,那么我们建立 TCP 连接需要多长时间?

  1. 建立 1 个 TCP 连接需要 3 x 延迟,即 3 x 100ms = 300ms。
  2. 我们必须这样做 31 次,一次用于页面,另外 30 次用于页面引用的其他文件。31 x 300 毫秒 = 9.3 秒。

9.3 秒建立 TCP 连接以加载引用 30 个其他文件的网页。这甚至不算发送 HTTP 请求和接收响应所花费的时间。

使用 HTTP Keep-Alive,我们只需要建立 1 个 TCP 连接,耗时 300 毫秒。

如果 HTTP Keep-Alive 如此出色,为什么不在服务器端也使用它呢?

HTTP 反向代理(如 HAproxy)通常部署在非常靠近它们代理的后端服务器的地方。在大多数情况下,反向代理与其后端服务器之间的延迟将在 1 毫秒以下,因此建立 TCP 连接比在客户端之间建立要快得多。

但这只是原因的一半。HTTP 服务器为每个客户端连接分配一定数量的内存。使用 Keep-Alive,它将保持连接处于活动状态,并且通过扩展它会在服务器上保持一定数量的内存在使用,直到达到 Keep-Alive 超时,这可能长达 15 秒,具体取决于服务器配置.

因此,如果我们考虑在 HTTP 反向代理的服务器端使用 Keep-Alive 的影响,我们正在增加对内存的需求,但由于代理和服务器之间的延迟如此之低,我们无法从减少了 TCP 的 3 次握手所花费的时间,因此在这种情况下,通常最好在代理和 Web 服务器之间禁用 Keep-Alive。

免责声明:是的,这个解释没有考虑到浏览器通常并行建立到服务器的多个 HTTP 连接的事实。但是,浏览器与同一主机建立的并行连接数量是有限制的,通常这仍然足够小,足以使保持活动成为可取的。

  • 感谢 Graeme 的出色解释,我从来没有花足够的时间回复问我这个问题的人,我肯定会保留这篇文章的链接,现在作为一个非常明确的回应:-) (5认同)
  • 如果代理和后端之间的连接是https,那么keepAlive在服务器端是否有优势? (2认同)

VBa*_*art 6

Nginx 支持两边保持活动。

  • 正如我所读到的,问题不是问 nginx 是否支持上游的 keep-alive,而是 nginx 是否支持禁用上游的 keep-alive。 (2认同)