【问题标题】:NodeJs-Cluster with Socket.IO and Namespaces带有 Socket.IO 和命名空间的 NodeJs-Cluster
【发布时间】:2021-02-27 04:01:25
【问题描述】:

我正在构建一个浏览器游戏。原型已经完成,现在我正在考虑如何扩展和托管它。我已经有一个“游戏服务器”,它目前处理一个游戏会话。一个游戏会话包含一个到 8 个玩家(最多)的 socketio 连接。

我想使用例如Node-Cluster 在同一个 docker-container 中有多个“游戏服务器”,每个游戏服务器应该处理一个或多个游戏会话,以便可以使用 cpu 的所有内核。 一个游戏会话仅供 8 位玩家使用,游戏会话应相互隔离。

据我所知,Node-Cluster 使我能够让所有子进程共享同一个端口。 我想为每个游戏会话设置一个名称空间(例如,玩家无论如何都连接到的浏览器中的 ID - 目标是:您获得一个发送给朋友以邀请他的 URL,类似于 skribble.io - https://localhost/?gameid=1234)。所以就我而言,加入命名空间基本上和加入游戏是一样的。

我的目标是拥有多个这些 docker-containers,并使用反向代理将传入连接路由到正确的容器,该容器处理游戏,在 url 中指定。 但这里的问题是,我不知道如何将连接转发到集群的正确子进程。

所以最终它应该如下所示:

 GameServerMaster [Maps ids to processes like: [ClusterNode1:[id1,id2,..]}
   - GameServerClusterNode1
     - GameSession1 [id1 io.off("/id1")]
     - GameSession2 [id2 io.off("/id2)]
     - ....
   - GameServerClusterNode2
     - GameSession3 [id3 io.off("/id3")]
     - GameSession4 [id4 io.off("/id4)]
     - ....

我找到了socket.io-redis,但这似乎有点过头了,因为没有广播——每场比赛都是孤立的。 (而且我不想只为这个用例托管 redis)

另外,我找到了sticky-session,但是通过使用它我不知道如何将传入连接转发到正确的进程,我认为它只是对它们进行负载平衡,这很糟糕,因为它必须路由到实际处理请求的游戏会话的那个 - 但我认为无论如何我都需要这样的东西,或者我是吗?

我正在做(或计划做)的事情是正确的方法吗?您对技术或架构有什么建议吗?

丢弃整个集群部分,只让 docker-container 处理一个“节点”来处理这些多个游戏会话会更好吗?

【问题讨论】:

    标签: javascript node.js socket.io node-cluster


    【解决方案1】:

    我发现自己处于同样的情况,我想出了以下解决方案。

    想法:

    您使用不同端口上的集群模块创建新进程。 使用主进程,您就像路由器一样。

    示例:

    在玩家加入房间之前,他询问路由器, (广播)123房间在哪里。路由器询问他的子进程 它们中的哪一个托管房间 123,并转发结果(例如端口 3001) 给客户。然后客户端连接到确切的进程。

    问题:

    如果多个子进程有相同的roomId,就会发生冲突, 但我想你会想办法避免这种情况, 即使发生这种情况的可能性非常低。

    需要注意的是,这个解决方案是使用你机器的所有核心,而不是分发到多台机器的解决方案。

    如果你想将它分发到多台机器上,你应该重新考虑 Redis 作为你的首选。

    【讨论】:

    • 感谢您的评论。我也在考虑这一点,但我也认为,在 docker 容器上打开端口范围只是糟糕架构的结果,尤其是当 node-cluster 提供端口共享功能时。但我想,这可能仍然是最可靠的解决方案,因为它不需要额外的依赖。
    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 2012-06-11
    • 2012-10-20
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多