我在亚马逊的AWS上运行了标准的LAMP EC2实例设置。安装了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。但是,Chrome调试有时会返回400请求返回原因{"code":1,"message":"Session ID unknown"}
,我想这是因为它正在与另一个实例进行通信。
另外,假设我在页面A上,并且套接字需要发送到页面B - 因为负载均衡器这两个页面可能位于不同的实例上(它们将同时打开)。据我所知,使用像Sticky Sessions这样的东西在那种情况下是行不通的,因为两个页面都会被限制在各自的实例中。
如何解决这个问题?我是否需要一个专门针对Node的专用实例?这似乎有点矫枉过正......
答案 0 :(得分:2)
当你考虑在一个只能一次检查一个层的负载均衡器上移动的websocket流量(第4层-ish)和HTTP流量(第7层)时,会出现问题。例如,如果将ELB设置为第7层(HTTP / HTTPS)上的负载平衡,那么websockets将无法在整个ELB中工作。但是,如果将ELB设置为第4层(TCP)上的负载平衡,则任何后备HTTP轮询请求都可能最终在任何上游服务器上。
这里有两种选择。您可以找到一种方法来有效地平衡HTTP和websocket请求,或者找到一种方法来确定性地将请求映射到上游服务器,而不管协议如何。
第一个非常复杂,需要另一个负载均衡器。 A good walkthrough can be found here。值得注意的是,当该帖子被写入时,HAProxy没有本地SSL支持。现在就是这种情况,如果那是你要去的路线,就可以完全删除ELB。如果是这样的话,第二种选择可能会更好。
否则,您可以单独使用HAProxy(或Nginx的付费版本)来实现确定性负载平衡机制。在这种情况下,您将使用IP哈希since socket.io does not provide a route-based mechanism to identify a particular server like sockjs。这将使用IP地址的前3个八位字节来确定哪个上游服务器获取每个请求,因此除非用户在HTTP轮询之间更改IP地址,否则这应该有效。
答案 1 :(得分:0)
解决方案是两个(或更多)node.js安装使用公共会话源。
以下是关于将REDIS用作node.js的常见会话存储的问题How to share session between NodeJs and PHP using Redis?
和另一个 Node.js Express sessions using connect-redis with Unix Domain Sockets