使用TCP负载均衡器代理W​​ebSockets而不使用粘性会话

Jus*_*zer 31 tcp load-balancing websocket node.js socket.io

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

我知道WebSockets的工作方式是首先从客户端发送HTTP升级请求,该请求由服务器通过发送正确处理密钥身份验证的响应来处理.在服务器发送该响应并且客户端批准后,该客户端与服务器之间存在双向连接.

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

Jan*_*cke 52

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

在较高级别,启动"WebSocket连接"要求客户端向HTTP服务器发送HTTP GET请求,而请求包括Upgrade头字段.现在,为了发生这个请求,客户端需要建立到HTTP服务器的TCP连接(这可能是显而易见的,但我认为重要的是明确指出这一点).然后,通过相同的 TCP连接发送后续HTTP服务器响应.

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

现在,根据RFC6455,WebSocket标准,在4.1节末尾:

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

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

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

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

如果您使用"session"引用了其他内容,那么它可能是由应用程序层引入的会话,我们无法对该会话进行评论.

根据您的评论进行修改:

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

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

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

是!

***有不同类型的负载平衡.根据类型,在两个端点之间建立连接后,负载平衡器的角色会有所不同.例子:

  • 如果负载平衡基于DNS发生,那么负载均衡器根本不涉及最终的TCP连接.它只是告诉客户端哪个主机必须直接连接.
  • 如果负载均衡器的工作方式类似于AWS的第4层ELB(这里是文档),那么它就是代理TCP连接.所以客户端实际上会将ELB本身视为服务器.然而,发生的事情是ELB只是在两个方向上转发包裹而没有改变.因此,它仍然大量参与TCP连接,只是透明.在这种情况下,实际上涉及两个永久TCP连接:一个从您到ELB,一个从ELB到服务器.这些在您的WebSocket连接的生命周期中也是永久性的.

  • @JustinMeltzer:您可能希望了解有状态和无状态协议之间的区别.虽然HTTP本身就是一种无状态协议,但您的问题很有意义 - 通常独立的HTTP请求的负载平衡是一个挑战.在HTTP的情况下保持一个客户端和一个后端服务器之间的对应关系需要技巧.但是,TCP连接是有状态且永久的.根据定义,在TCP连接的情况下保持客户端和后端服务器之间的对应关系.如果违反此原则,则不再是TCP连接. (3认同)
  • ad 1)"有状态"和"无状态"是适用于许多情况的概念.你可以阅读很多关于它的内容.关于协议,你可以从这里开始:http://en.wikipedia.org/wiki/Stateless_protocol - ad 2)ELB必须实现一种直接连接客户端< - > ELB和ELB < - >后端的机制.为简单起见,您可以将其视为查找表. (2认同)

obe*_*tet 5

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

它需要粘性.这与能够基于每个HTTP请求分派的L7 HTTP LB不同.

LB可以通过不同的方法工作,即

  • 将源IP /端口哈希到一组活动后端服务器
  • 在TCP连接建立后,选择一个后端服务器并记住它