首页 文章

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

提问于
浏览
30

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

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

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

2 回答

  • 5

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

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

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

    • 将源IP /端口哈希到一组活动后端服务器

    • Build TCP连接后,选择后端服务器并记住

  • 49

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

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

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

    现在,根据RFC6455,WebSocket标准,在section 4.1结尾:

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

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

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

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

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

    Edit with respect to your comments:

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

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

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

    是!

    ***有不同类型的负载 balancer . 根据类型,在两个 endpoints 之间 Build 连接后,负载 balancer 器的角色会有所不同 . 例子:

    • 如果基于DNS进行负载 balancer ,那么负载均衡器根本不涉及最终的TCP连接 . 它只是告诉客户端哪个主机必须连接 directly .

    • 如果负载均衡器的工作方式类似于AWS的第4层ELB(docs here),那么它代表TCP连接 . 所以客户端实际上会将ELB本身视为服务器 . 然而,会发生什么是ELB只是在两个方向上转发包,没有改变 . 因此,它仍然大量参与TCP连接,只是透明 . 在这种情况下,实际上涉及两个永久TCP连接:一个从您到ELB,一个从ELB到服务器 . 这些在您的WebSocket连接的生命周期中也是永久性的 .

相关问题