HAProxy 能够在客户端(客户端 <-> HAProxy)启用 HTTP 保持活动,但在服务器端(HAProxy <-> 服务器)禁用它。
我们的一些客户通过卫星连接到我们的网络服务,因此延迟约为 600 毫秒,我认为通过启用保持活动功能,可以加快速度。我说得对吗?
Nginx 支持此功能吗?这是其他软件和硬件负载均衡器中广泛实现的功能吗?除了 HAProxy 之外还有什么?
答案1
编辑:我的回答仅涵盖原始未编辑的问题,即这种事情在负载平衡器/反向代理中是否很常见。我不确定 nginx/产品 X 是否支持此功能,99.9% 的反向代理经验都是使用 HAproxy。
正确。HTTP Keep-Alive 在客户端,但在服务器端不是。
为什么?
如果您分解一些细节,您很快就能明白为什么这是一项优势。在此示例中,我们假设正在加载页面 www.example.com,该页面包含 3 张图片,img[1-3].jpg。
浏览器加载页面,没有 Keep-Alive
- 客户端在端口 80 上与 www.example.com 建立 TCP 连接
- 客户端对“/”发出 HTTP GET 请求
- 服务器发送 URI“/”的 HTML 内容(其中包括引用 3 个图像的 HTML 标签)
- 服务器关闭 TCP 连接
- 客户端在端口 80 上与 www.example.com 建立 TCP 连接
- 客户端对“/img1.jpg”发出 HTTP GET 请求
- 服务器发送图像
- 服务器关闭 TCP 连接
- 客户端在端口 80 上与 www.example.com 建立 TCP 连接
- 客户端对“/img2.jpg”发出 HTTP GET 请求
- 服务器发送图像
- 服务器关闭 TCP 连接
- 客户端在端口 80 上与 www.example.com 建立 TCP 连接
- 客户端对“/img3.jpg”发出 HTTP GET 请求
- 服务器发送图像
- 服务器关闭 TCP 连接
请注意,有 4 个单独的 TCP 会话建立然后关闭。
浏览器加载页面,使用 Keep-Alive
HTTP Keep-Alive 允许单个 TCP 连接依次处理多个 HTTP 请求。
- 客户端在端口 80 上与 www.example.com 建立 TCP 连接
- 客户端对“/”发出 HTTP GET 请求,并要求服务器使其成为 HTTP Keep-Alive 会话。
- 服务器发送 URI“/”的 HTML 内容(其中包括引用 3 个图像的 HTML 标签)
- 服务器没有关闭TCP 连接
- 客户端对“/img1.jpg”执行 HTTP GET 请求
- 服务器发送图像
- 客户端对“/img2.jpg”执行 HTTP GET 请求
- 服务器发送图像
- 客户端对“/img3.jpg”执行 HTTP GET 请求
- 服务器发送图像
- 如果在 HTTP Keep-Alive 超时期限内未收到任何 HTTP 请求,服务器将关闭 TCP 连接
请注意,使用 Keep-Alive 时,只会建立 1 个 TCP 连接,并且最终会关闭。
为什么 Keep-Alive 更好?
要回答这个问题,您必须了解在客户端和服务器之间建立 TCP 连接需要什么。这称为 TCP 三次握手。
- 客户端发送 SYN(chronise)数据包
- 服务器发回 SYN(chronise)ACK(确认),SYN-ACK
- 客户端发送 ACK(确认)数据包
- TCP 连接现在被客户端和服务器视为处于活动状态
网络存在延迟,因此三次握手中的每一步都需要一定的时间。假设客户端和服务器之间有 30 毫秒,建立 TCP 连接所需的来回发送 IP 数据包意味着需要 3 x 30 毫秒 = 90 毫秒才能建立 TCP 连接。
这听起来可能不多,但如果我们考虑到在原始示例中,我们必须建立 4 个单独的 TCP 连接,那么这将变成 360 毫秒。如果客户端和服务器之间的延迟是 100 毫秒而不是 30 毫秒会怎样?那么我们的 4 个连接需要 1200 毫秒才能建立。
更糟糕的是,典型的网页可能需要加载的远不止 3 张图片,客户端可能需要请求多个 CSS、JavaScript、图像或其他文件。如果页面加载了 30 个其他文件,并且客户端-服务器延迟为 100 毫秒,那么我们需要花多长时间建立 TCP 连接?
- 建立1个TCP连接需要3 x延迟,即3 x 100ms = 300ms。
- 我们必须执行此操作 31 次,一次针对页面,另外 30 次针对页面引用的每个其他文件。31 x 300 毫秒 = 9.3 秒。
建立 TCP 连接加载引用 30 个其他文件的网页耗时 9.3 秒。这还不包括发送 HTTP 请求和接收响应所用的时间。
使用HTTP Keep-Alive,我们只需要建立1个TCP连接,这需要300毫秒。
如果 HTTP Keep-Alive 如此好,为什么不在服务器端也使用它呢?
HTTP 反向代理(如 HAproxy)通常部署在距离其代理的后端服务器非常近的地方。在大多数情况下,反向代理与其后端服务器之间的延迟将低于 1ms,因此建立 TCP 连接比在客户端之间建立连接要快得多。
但这只是原因的一半。HTTP 服务器为每个客户端连接分配一定量的内存。使用 Keep-Alive,它将保持连接处于活动状态,并且通过扩展它将在服务器上保留一定量的内存,直到达到 Keep-Alive 超时,这可能最多为 15 秒,具体取决于服务器配置。
因此,如果我们考虑在 HTTP 反向代理的服务器端使用 Keep-Alive 的影响,我们就会增加对内存的需求,但由于代理和服务器之间的延迟非常低,我们并没有从减少 TCP 三次握手所用时间中获得任何实际好处,所以在这种情况下,最好禁用代理和 Web 服务器之间的 Keep-Alive。
免责声明:是的,这个解释没有考虑到浏览器通常会并行建立多个与服务器的 HTTP 连接这一事实。但是,浏览器与同一主机建立的并行连接数是有限制的,而且通常这个限制仍然足够小,足以使保持活动状态成为可取的。
答案2
Nginx 支持双方保持连接。