37

我想使用 Amazon Elastic Load Balancer 将 WebSocket 连接代理到多个 node.js 服务器。由于 Amazon ELB 不提供实际的 WebSocket 支持,因此我需要使用它的 vanilla TCP 消息传递。但是,我试图了解如果没有某种粘性会话功能,这将如何工作。

我了解 WebSockets 通过首先从客户端发送 HTTP 升级请求来工作,该请求由服务器通过发送正确处理密钥身份验证的响应来处理。在服务器发送该响应并得到客户端的批准后,该客户端和服务器之间就建立了双向连接。

但是,假设客户端在批准服务器响应后,将数据发送到服务器。如果它将数据发送到负载均衡器,然后负载均衡器将该数据中继到未处理原始 WebSocket 升级请求的不同服务器,那么这个新服务器将如何知道 WebSocket 连接?还是客户端会自动绕过负载平衡器,直接将数据发送到处理初始升级的服务器?

4

2 回答 2

63

我认为为了回答这个问题,我们需要了解的是,在整个 WebSocket 创建过程中,底层 TCP 连接究竟是如何演变的。您将意识到WebSocket连接的关键部分是底层 TCP 连接本身。我不确定您在 WebSockets 上下文中的“会话”是什么意思。

在高层次上,启动“WebSocket 连接”需要客户端向 HTTP 服务器发送 HTTP GET 请求,而该请求包含Upgrade标头字段。现在,为了让这个请求发生,客户端需要建立到 HTTP 服务器的 TCP 连接(这可能很明显,但我认为在这里明确指出这一点很重要)。随后的 HTTP 服务器响应随后通过相同的TCP 连接发送。

请注意,现在,在发送服务器响应后,如果客户端或服务器没有主动关闭 TCP 连接,TCP 连接仍然是打开/活动的。

现在,根据 RFC 6455,WebSocket 标准,在第 4.1 节的末尾:

如果服务器的响应按照上面的规定进行验证,则
表示WebSocket 连接已建立并且
WebSocket 连接处于 OPEN 状态

我从这里读到,客户端在发送初始 HTTP GET(升级)请求之前启动的同一 TCP 连接将保持打开状态,从现在开始将用作全双工 WebSocket 连接的传输层。这是有道理的!

关于您的问题,这意味着负载均衡器只会在发出初始 HTTP GET(升级)请求之前发挥作用,即两个通信端点之间建立所述 WebSocket 连接创建所涉及的唯一一个 TCP 连接之前. 此后,TCP 连接保持建立,并且不能被中间的网络设备“重定向”。

我们可以得出结论——在你的会话术语中——TCP 连接定义了会话。只要 WebSocket 连接处于活动状态(即未终止),它就根据定义提供并存在于自己的会话中。没有什么可以改变这个会话。然而,在这张图片中,两个独立的 WebSocket 连接不能共享同一个会话。

如果您使用“会话”来引用其他内容,那么它可能是应用层引入的会话,我们无法对此发表评论。

编辑关于您的评论:

所以你说负载均衡器不参与 TCP 连接

不,这不是真的,至少在一般情况下是这样。它肯定会影响 TCP 连接的建立,从某种意义上说,它可以决定如何处理客户端连接尝试。具体取决于负载均衡器的确切类型(*,见下文)。重要提示:在两个端点之间建立连接后——虽然我不认为负载均衡器是一个端点,但我指的是 WebSocket 客户端和 WebSocket 服务器——这两个端点在 WebSocket 连接的生命周期内将不再改变. 负载均衡器可能*仍在网络路径中,但可以假定不再受到影响。

因此全双工连接是在客户端和端服务器之间?

是的!

***有不同类型的负载平衡。根据类型的不同,负载均衡器在两个端点之间建立连接后的作用是不同的。例子:

  • 如果负载平衡发生在 DNS 基础上,那么负载平衡器根本不参与最终的 TCP 连接。它只是告诉客户端必须直接连接到哪个主机。
  • 如果负载均衡器的工作方式类似于 AWS 的第 4 层 ELB(此处的文档),那么可以说代理 TCP 连接。因此,客户端实际上会将 ELB 本身视为服务器。然而,发生的情况是 ELB 只是在两个方向上转发包,而不做任何更改。因此,它仍然大量参与 TCP 连接,只是透明的。在这种情况下,实际上涉及两个永久 TCP 连接:一个从您到 ELB,一个从 ELB 到服务器。在您的 WebSocket 连接的整个生命周期内,这些都是永久性的。
于 2013-03-07T12:08:26.007 回答
7

WebSocket 使用持久的 TCP 连接,因此需要将该 TCP 连接的所有 IP 数据包转发到同一后端服务器(在 TCP 连接的生命周期内)。

它需要有粘性。这与能够基于每个 HTTP 请求进行调度的 L7 HTTP LB 不同。

LB 可以通过不同的方法进行粘性工作,即

  • 将源 IP/端口散列到一组活动的后端服务器
  • 在 TCP 连接建立后,选择一个后端服务器并记住
于 2013-03-07T16:26:06.400 回答