【问题标题】:Node socket.io on load balanced Amazon EC2负载平衡 Amazon EC2 上的节点 socket.io
【发布时间】:2015-06-27 16:14:56
【问题描述】:

我有一个在亚马逊 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 的完整实例?这似乎有点矫枉过正......

【问题讨论】:

    标签: node.js sockets amazon-web-services amazon-ec2


    【解决方案1】:

    当您考虑 websocket 流量(第 4 层 -ish)和 HTTP 流量(第 7 层)在一次只能检查一层的负载均衡器上移动时,就会出现问题。例如,如果您将 ELB 设置为在第 7 层 (HTTP/HTTPS) 上进行负载平衡,那么 Websocket 将根本无法在 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 地址,否则这应该可以工作。

    【讨论】:

    • 谢谢,我会看看 HAProxy - 哈希 IP 听起来像是我需要使用的东西。
    【解决方案2】:

    解决方案是让两个(或更多)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

    【讨论】:

    • 但这是否适用于 socket.io?它肯定指向会话管理问题。我们在负载平衡的 EC2 服务器上使用 MySQL、Mongo 和 Dynamo 在 Node 中进行会话管理,它们都可以工作。 Express 允许插件来处理这个问题,并且它们存在于所有上述数据库中。但是我没有用socket.io尝试过。值得调查,但之前的答案可能指向实际问题。
    • 当你有公共会话存储时,它应该在 Express 中工作,就像在 Node.js 中一样。公共会话存储是将其保持在一起的粘合剂。这样你就不用依赖 ELB 来维护客户端 1 到服务器 B。客户端 1 可以被发送到任何可用的服务器,它会找到会话并处理事务。
    猜你喜欢
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 2012-08-10
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多