【问题标题】:Setting up websockets in a multi-instance node environment using PM2使用 PM2 在多实例节点环境中设置 websocket
【发布时间】:2024-01-18 07:35:02
【问题描述】:

我当前的设置是使用 PM2 运行多个节点实例来管理实例并充当负载均衡器。

我想使用 websockets 实现一些功能。 想到的第一个问题是在 X 节点实例之间共享套接字。

我的理解是,如果我在节点 env 中启动 websocket-server,则只有该 env 才能访问与其连接的套接字。 我不想为每个用户的每个实例加载 Web 套接字,因为这看起来很浪费资源。

目前我正在使用 npm 上的 websocket 包,但如果有更好的选择,我绝不会与此相关。

我希望套接字或多或少地将数据从服务器推送到客户端,并避免从客户端到服务器的任何内容。

到目前为止,我的解决方案是启动另一个仅充当 websocket 服务器的节点实例。

这将允许用户像往常一样向普通实例发出所有请求,但与专用于套接字的单独节点实例建立 websocket 连接。

然后,服务对象可以在任何更新内容时向专用套接字服务器发送消息,以将数据发送回适当的客户端。

我不确定这是不是最好的选择,我正在尝试查看是否有其他推荐的方法来管理跨多个节点实例的 websocket,但仍然允许我根据需要启动/关闭节点实例。

【问题讨论】:

    标签: node.js websocket pm2


    【解决方案1】:

    我建议您避免复杂的设置,让 socket.io 跨多个节点工作,从而分配负载;如果您想避免数据从客户端传到服务器,请不要监听服务器上的传入事件。

    Socket.io 支持多节点,条件如下:

    • 您已启用sticky sessions。这可确保请求连接回它们源自的进程。

    • 您使用一个名为 socket.io-redis 的特殊适配器和一个小型 Redis 实例作为存储中心点 - 它跟踪命名空间/房间连接的套接字跨节点集群。

    这是一个例子:

    // setup io as usual
    const io = require('socket.io')(3000)
    
    // Set a redisAdapter as an adapter.
    const redisAdapter = require('socket.io-redis')
    io.adapter(redisAdapter({ host: 'localhost', port: 6379 }))
    

    从那时起,一切照旧:

    io.emit('hello', 'to all clients')
    

    您可以在此处阅读更多内容:Socket.IO - Using Multiple Nodes

    【讨论】: