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


30

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

我们的一些客户通过卫星连接到我们的Web服务,因此延迟约为600毫秒,我认为通过启用保持活动状态,可以使速度加快一点。我对吗?

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

Answers:


43

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

正确。HTTP保持活动在客户端,但不在服务器端。

为什么?

如果您分解了一些细节,则可以快速了解为什么这样做有好处。对于此示例,假设我们正在加载一个页面www.example.com,并且该页面包含3个图像,即img [1-3] .jpg。

浏览器正在加载页面,而没有保持活动状态

  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会话。

浏览器加载页面,保持活动状态

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. 客户端这样做,并且HTTP GET请求为“ /img1.jpg”
  6. 服务器发送图像
  7. 客户端这样做,并且HTTP GET请求为“ /img2.jpg”
  8. 服务器发送图像
  9. 客户端这样做,并且HTTP GET请求为“ /img3.jpg”
  10. 服务器发送图像
  11. 如果在其HTTP保持活动超时时间内没有收到更多HTTP请求,则服务器将关闭TCP连接

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

为什么保持生命更好?

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

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

网络具有延迟,因此三向握手的每个步骤都需要一定的时间。可以说,客户端和服务器之间有30毫秒的时间,来回建立IP连接所需的IP数据包的发送意味着建立TCP连接需要3 x 30毫秒= 90毫秒。

这听起来可能并不多,但是如果我们认为在原始示例中,我们必须建立4个独立的TCP连接,则该时间将变为360ms。如果客户端和服务器之间的延迟是100ms而不是30ms怎么办?然后我们的4个连接需要1200毫秒才能建立。

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

  1. 建立1个TCP连接需要3倍的等待时间,即3 x 100毫秒= 300毫秒。
  2. 我们必须这样做31次,一次是针对该页面,另一次是30次针对该页面引用的其他文件。31 x 300ms = 9.3秒。

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

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

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

HTTP反向代理(例如HAproxy)通常部署在非常接近它们所代理的后端服务器的位置。在大多数情况下,反向代理与其后端服务器之间的等待时间将小于1毫秒,因此建立TCP连接比在客户端之间建立连接要快得多。

但这只是原因的一半。HTTP服务器为每个客户端连接分配一定数量的内存。使用Keep-Alive,它将使连接保持活动状态,并且通过扩展,它将保持服务器上使用的一定数量的内存,直到达到Keep-Alive超时时间为止,根据服务器配置的不同,最长可达15s。 。

因此,如果我们考虑在HTTP反向代理的服务器端使用Keep-Alive的效果,我们会增加对内存的需求,但是由于代理与服务器之间的延迟非常低,因此,我们并没有从中获得真正的收益。减少了TCP三向握手所花费的时间,因此,在这种情况下,通常最好禁用代理和Web服务器之间的Keep-Alive。

免责声明:是的,此解释未考虑到浏览器通常会并行建立与服务器的多个HTTP连接这一事实。但是,浏览器将与同一主机建立多少个并行连接是有限制的,通常,此连接的大小仍然足够小,可以保持活动状态。


5
感谢Graeme的出色解释,我一直没有花那么多时间回答有人问我这个问题,所以我现在肯定会保留一个链接,以作为一个非常明确的答复:-)
Willy Tarreau

2
如果代理和后端之间的连接为https,则在服务器端使用keepAlive是否会有优势?
avmohan '16

“ HTTP服务器为每个客户端连接分配一定数量的内存”是的,但是这些连接很少(?)每个负载均衡器仅一个?互联网上的每个客户端都没有一个(?)
Raedwald

@Raedwald,如果您的负载平衡器仅限于与每个支持的服务器建立单个HTTP连接,那么您将经历一段非常糟糕的时光。:-)
ThatGraemeGuy

7

Nginx在两侧都支持保持活动。


如果代理和后端之间存在延迟,您是否说保持活动状态对后端有用?另外,允许保持连接的最佳数量是多少?
CMCDragonkai 2014年

@CMCDragonkai如果您的后端位于专用服务器上,那么避免依赖于您网络的连接延迟可能会很有用。绝非易事,最佳数目主要取决于您的设置,您的环境,您的应用程序和请求模式。
VBart 2014年

我希望找到一个方程式来解决这个问题!
CMCDragonkai 2014年

2
在我读到它时,问题不是在询问nginx是否在上游支持保持活动,而是问nginx是否支持在上游禁止保持活动。
user45793 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.