在负载平衡的Amazon EC2上节点socket.io

我有一个标准的LAMP EC2实例设置在Amazon的AWS上运行。 在安装Node.js,socket.io和Express以满足实时更新的需求的同时,我正处于应用程序负载平衡的阶段。 这一切都工作,但我的套接字不是。 这是我的设置看起来如何:

--- EC2 >> Node.js + socket.io / Client >> ELB -- \ --- EC2 >> Node.js + socket.io [RDS MySQL - EC2 instances communicate to this] 

正如你所看到的,每个实例都有一个Node和socket.io的安装。 然而,偶尔Chromedebugging将会返回原因{"code":1,"message":"Session ID unknown"}的套接字请求,我猜这是因为它正在与其他实例进行通信。

另外,假设我在页面A上,并且套接字需要发送到页面B–由于负载均衡器,这两个页面可能在不同的实例上(它们都将同时打开)。 据我所知,使用“粘滞会话”这样的东西在这种情况下是行不通的,因为这两个页面将被限制在它们各自的实例中。

我怎样才能解决这个问题? 我需要一个专门用于Node的专用实例吗? 这似乎有点矫枉过正…

当您考虑websocketstream量(第4层 – stream量)和HTTPstream量(第7层)在负载均衡器上移动时,问题就会出现,负载均衡器一次只能检查一个层。 例如,如果您将ELB设置为第7层(HTTP / HTTPS)上的负载平衡,则WebSockets在ELB中将不起作用。 但是,如果将ELB设置为第4层(TCP)上的负载平衡,则任何回退HTTP轮询请求都可能会在任何上游服务器上结束。

你有两个select。 您可以想出一种有效地平衡HTTP和WebSocket请求的方法,或者find一种确定性地将请求映射到上游服务器的方法,而不pipe协议如何。

第一个很相关,需要另一个负载平衡器。 可以在这里find一个很好的演练 。 值得注意的是,当写这篇文章HAProxy没有本地SSL支持。 现在情况就是这样,可能完全删除ELB,如果这是你想要去的路线。 如果是这种情况,第二种select可能会更好。

否则,您可以使用HAProxy(或Nginx的付费版本)来实现确定性的负载平衡机制。 在这种情况下,您将使用IP散列, 因为socket.io不提供基于路由的机制来识别像sockjs这样的特定服务器 。 这将使用IP地址的前3个字节来确定哪个上游服务器获取每个请求,除非用户更改HTTP轮询之间的IP地址,否则这应该工作。

解决方法是将两个(或更多)node.js安装为使用通用会话源。

这里有一个关于使用REDIS作为node.js的公共会话存储的问题如何使用Redis在NodeJs和PHP之间共享会话?

另一个使用connect-redis和Unix域套接字的Node.js Express会话