我想使用Amazon Elastic Load Balancer将WebSocket连接代理到多个node.js服务器。由于Amazon ELB不提供实际的WebSocket支持,我需要使用其vanilla TCP消息传递。但是,我试图了解如果没有某种粘性会话功能,这将如何工作。
据我所知,WebSockets的工作方式是首先从客户端发送HTTP升级请求,该请求由服务器通过发送正确处理密钥身份验证的响应来处理。服务器发送该响应并且客户端批准后,该客户端与服务器之间存在双向连接。
但是,假设客户端在批准服务器响应后将数据发送到服务器。如果它将数据发送到负载均衡器,然后负载均衡器将该数据中继到不处理原始WebSocket升级请求的其他服务器,那么这个新服务器将如何知道WebSocket连接?或者客户端是否会自动绕过负载均衡器并将数据直接发送到处理初始升级的服务器?
答案 0 :(得分:52)
我认为,为了回答这个问题,我们需要理解的是,在整个WebSocket创建过程中,底层TCP连接究竟是如何演变的。您将意识到WebSocket连接的 sticky 部分是底层TCP连接本身。我不确定你在WebSockets的上下文中对“session”的意思。
在较高级别,启动“WebSocket连接”要求客户端向HTTP服务器发送HTTP GET请求,而请求包含Upgrade
标头字段。现在,为了发生这个请求,客户端需要建立到HTTP服务器的TCP连接(这可能是显而易见的,但我认为重要的是明确指出这一点)。然后,通过相同的 TCP连接发送后续HTTP服务器响应。
请注意,现在,在发送服务器响应之后,如果客户端或服务器未主动关闭TCP连接,则TCP连接仍处于打开/活动状态。
现在,根据RFC 6455,WebSocket标准,在section 4.1的末尾:
如果服务器的响应按上述规定验证,则为
说 WebSocket连接建立并且即 WebSocket连接处于OPEN状态
我从这里读到,在发送初始HTTP GET(升级)请求之前由客户端发起的相同TCP连接将保持打开状态,并且从现在起将用作全双工WebSocket连接的传输层。这是有道理的!
关于您的问题,这意味着负载均衡器只会在发出初始HTTP GET(升级)请求之前扮演角色,即之前只有在两个通信端点之间建立所述WebSocket连接创建中涉及的TCP连接。此后,TCP连接保持建立状态,并且不能被中间的网络设备“重定向”。
我们可以得出结论 - 在您的会话术语中 - TCP连接定义会话。只要WebSocket连接处于活动状态(即未终止),按照定义就会提供并存在于自己的会话中。什么都不能改变这个会话。在这张图片中,两个独立的WebSocket连接无法共享同一个会话。
如果您使用“session”引用了其他内容,那么它可能是应用程序层引入的会话,我们无法对该会话发表评论。
根据您的评论进行修改:
所以你说负载均衡器不参与TCP 连接
不,这不是真的,至少在一般情况下如此。它肯定会影响TCP连接建立,因为它可以决定如何处理客户端连接尝试。具体情况取决于负载均衡器的确切类型(*,见下文)。重要:在两个端点之间建立连接之后 - 虽然我不认为负载均衡器是端点,但我指的是WebSocket客户端和WebSocket服务器 - 两个端点在WebSocket连接的生命周期内不会再发生变化。负载均衡器可能仍然在网络路径中,但可以假设不再受影响。
因此全双工连接是在客户端和 终端服务器?
是!
***有不同类型的负载平衡。根据类型,在两个端点之间建立连接后,负载平衡器的角色会有所不同。例子:
答案 1 :(得分:5)
WebSocket使用持久性TCP连接,因此要求将该TCP连接的所有IP数据包转发到同一后端服务器(在TCP连接的生命周期内)。
它需要粘性。这与能够基于每个HTTP请求进行分派的L7 HTTP LB不同。
LB可以通过不同的方法发挥作用,即