使用 TCP 负载平衡器代理 WebSockets 没有粘性会话 [英] Proxying WebSockets with TCP load balancer without sticky sessions

查看:17
本文介绍了使用 TCP 负载平衡器代理 WebSockets 没有粘性会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to proxy WebSocket connections to multiple node.js servers using Amazon Elastic Load Balancer. Since Amazon ELB does not provide actual WebSocket support, I would need to use its vanilla TCP messaging. However, I'm trying to understand how this would work without some sort of sticky session functionality.

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

I understand that WebSockets work by first sending an HTTP Upgrade request from the client, which is handled by the server by sending a response which correctly handles key authentication. After the server sends that response and it is approved by the client, there is a bidirectional connection between that client and server.

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

However let's say the client, after approving the server response, sends data to the server. If it sends the data to the load balancer, and the load balancer then relays that data to a different server that did not handle the original WebSocket Upgrade request, then how will this new server be aware of the WebSocket connection? Or will the client automatically bypass the load balancer and send data directly to the server that handled the initial upgrade?

推荐答案

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

I think what we need to understand in order to answer this question is how exactly the underlying TCP connection evolves during the whole WebSocket creation process. You will realize that the sticky part of a WebSocket connection is the underlying TCP connection itself. I am not sure what you mean with "session" in the context of WebSockets.

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

At a high level, initiating a "WebSocket connection" requires the client to send an HTTP GET request to an HTTP server whereas the request includes the Upgrade header field. Now, for this request to happen the client needs to have established a TCP connection to the HTTP server (that might be obvious, but I think here it is important to point this out explicitly). The subsequent HTTP server response is then sent through the same TCP connection.

请注意,现在,在发送服务器响应后,如果客户端或服务器未主动关闭 TCP 连接,则 TCP 连接仍处于打开/活动状态.

Note that now, after the server response has been sent, the TCP connection is still open/alive if not actively closed by either the client or the server.

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

Now, according to RFC 6455, the WebSocket standard, at the end of section 4.1:

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

If the server's response is validated as provided for above, it is
said that The WebSocket Connection is Established and that the
WebSocket Connection is in the OPEN state

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

I read from here that the same TCP connection that was initiated by the client before sending the initial HTTP GET (Upgrade) request will just be left open and will from now on serve as the transport layer for the full-duplex WebSocket connection. And this makes sense!

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

With respect to your question this means that a load balancer will only play a role before the initial HTTP GET (Upgrade) request is made, i.e. before the one and only TCP connection involved in said WebSocket connection creation is established between the two communication end points. Thereafter, the TCP connection stays established and cannot become "redirected" by a network device in between.

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

We can conclude that -- in your session terminology -- the TCP connection defines the session. As long as a WebSocket connection is alive (i.e. is not terminated), it by definition provides and lives in its own session. Nothing can change this session. Speaking in this picture, two independent WebSocket connections, however, cannot share the same session.

如果你用session"来指代其他东西,那么它很可能是一个由应用层引入的会话,我们无法评论那个.

If you referred to something else with "session", then it probably is a session that is introduced by the application layer and we cannot comment on that one.

根据您的评论进行

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

so you're saying that the load balancer is not involved in the TCP connection

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

No, that is not true, at least in general. It definitely can take influence upon TCP connection establishment, in the sense that it can decide what to do with the client connection attempt. The specifics depend on the exact type of load balancer (* , see below). Important: After the connection is established between two endpoints -- whereas I don't consider the load balancer to be an endpoint, I refer to WebSocket client and WebSocket server -- the two endpoints will not change anymore for the lifetime of the WebSocket connection. The load balancer might* still be in the network path, but can be assumed to not take influence anymore.

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

Therefore the full-duplex connection is between the client and the end server?

是的!

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

***There are different types of load balancing. Depending on the type, the role of the load balancer is different after connection establishment between the two end points. Examples:

  • 如果负载平衡基于 DNS 发生,那么负载平衡器根本不参与最终的 TCP 连接.它只是告诉客户端必须直接连接到哪个主机.
  • 如果负载均衡器的工作方式类似于 AWS 的第 4 层 ELB (docs here),那么可以说代理 TCP 连接.因此,客户端实际上会将 ELB 本身视为服务器.然而,发生的情况是 ELB 只是在两个方向上转发包,没有改变.因此,它仍然大量参与 TCP 连接,只是透明的.在这种情况下,实际上涉及两个永久的 TCP 连接:一个从您到 ELB,一个从 ELB 到服务器.这些在您的 WebSocket 连接的整个生命周期内都是永久的.
  • If the load balancing happens on DNS basis, then the load balancer is not involved in the final TCP connection at all. It just tells the client to which host is has to connect directly.
  • If the load balancer works like the Layer 4 ELB from AWS (docs here), then it so to say proxies the TCP connection. So the client would actually see the ELB itself as the server. What happens, however, is that the ELB just forwards the packages in both directions, without change. Hence, it is still heavily involved in the TCP connection, just transparently. In this case there are actually two permanent TCP connections involved: one from you to the ELB, and one from the ELB to the server. These are again permanent for the lifetime of your WebSocket connection.

这篇关于使用 TCP 负载平衡器代理 WebSockets 没有粘性会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆