7

我的情况是,我们目前正在编写一个在线应用程序,它在服务器端使用 Node.js 和 WebSocket 侦听器。我们有两个不同的部分:一个提供页面并使用 node.js 和 express+ejs,另一个是一个完全不同的应用程序,它只包含用于 websockets 的 socket.io 库。所以这里我们来讨论这个websockets部分的可扩展性问题。

我们发现的一种解决方案是使用 redis 并在服务器之间共享套接字信息,但由于架构的原因,它需要共享其他信息的负载,这将在服务器上产生巨大的开销。

在这个介绍之后,我的问题是 - 是否可以对 websockets 使用基于 cookie 的负载平衡?因此,可以说来自 cookie server=server1 的用户的每个连接都将始终转发到 server1,并且 cookie server=server2 的每个连接都将转发到 server2,而没有此类 cookie 的连接将转发到最不繁忙的服务器。

更新:正如一个“答案”所说——是的,我知道这存在。只是不记得那个名字是粘性会话。但问题是——这适用于 websockets 吗?有没有可能的并发症?

4

1 回答 1

5

我们的 Node.js 生产堆栈中出现了类似的问题。我们有两台使用 WebSockets 的服务器,它们适用于正常用例,但偶尔负载均衡器会在两台服务器之间反弹这些连接,这会导致问题。(我们在后端有会话代码应该已经修复它,但没有正确处理它。)

我们尝试在这些服务器前的梭子鱼负载均衡器上启用 Sticky Session,但发现由于其运行方式,它会阻止 WebSocket 流量。我没有研究确切原因,因为在线可用的信息很少,但似乎这是由于平衡器如何剥离 HTTP 请求的标头,获取 cookie,并将请求转发到正确的后端服务器。由于 WebSockets 以 HTTP 开始,但随后升级,负载均衡器没有注意到连接的差异,并会尝试执行相同的 HTTP 处理。这将导致 WebSocket 连接失败,从而断开用户连接。

以下是我们目前所拥有的,运行良好。我们仍然在后端服务器前使用梭子鱼负载均衡器,但我们没有在负载均衡器上启用粘性会话。在我们的后端服务器上,我们的应用服务器前面是 HAProxy,它确实支持 WebSocket,并且可以以“迂回”的方式提供粘性会话。


请求流列表

  1. 传入的客户端请求命中主梭子鱼负载均衡器
  2. 负载均衡器转发到任一活动后端服务器
  3. HAProxy 接收请求并检查新的“粘性 cookie”
  4. 基于 cookie,HAProxy 转发到正确的后端应用服务器

请求流程图

 WebSocket Request  /--> Barracuda 1 -->\   /--> Host 1 -->\   /--> App 1
------------------->                     -->                -->
                    \--> Barracuda 2 -->/   \--> Host 2 -->/   \--> App 1

当箭头返回一个请求时,这意味着请求可以流向流中的任一点。


HAProxy 配置详细信息

backend app_1
   cookie ha_app_1 insert
   server host1 10.0.0.101:80011 weight 1 maxconn 1024 cookie host_1 check
   server host2 10.0.0.102:80011 weight 1 maxconn 1024 cookie host_2 check

在上面的配置中:

  • cookie ha_app_1 insert是实际使用的 cookie 名称
  • cookie host_1 checkcookie host_2 check设置 cookie 值
于 2012-08-08T20:36:31.400 回答