3

这是和以前一样的问题:

node.js 子进程

我在问我是否应该为我的 node.js 游戏在每场比赛中使用一个子进程。

但是我意识到以前我忽略了一些非常重要的细节。

游戏允许玩家以某些有限的方式操纵游戏规则。然而,这仍然会导致无限循环/内存泄漏/停顿和崩溃。

每场比赛 1 个流程是可扩展/合理的想法吗?

4

5 回答 5

4

如果任何一个游戏进程都可以吃掉所有的内存或 CPU,那么这是不可扩展的。如果您的服务器是 8 核机器,则八个游戏可能会占用所有 CPU 时间,您无能为力,除了通过监视进程top并根据需要杀死它们 - 但这会使服务器变得颠簸。

现在,如果您首先设法阻止这些事情(对我来说听起来是一个更好的主意),那么它可行的。每个进程将占用 30mb 以上的内存,因此每几百个进程就需要一个强大的服务器。以http://site.nodester.com为例,它们似乎在一台机器上运行了大约 600 个进程。他们的软件堆栈也是开源的:https ://github.com/nodester/nodester

node v0.8将带来Isolates (无共享线程),这可能会比子进程使用更少的资源。

一个更“严肃”的解决方案是使用某种虚拟化,如OpenVZ,它允许您设置资源限制,然后只保留一个可用的虚拟服务器池,每个游戏都有自己的。它并不像看起来那么重,每台服务器的开销约为 18mb,每台机器可以托管数百个,尽管它的设置要复杂得多。

于 2011-11-19T17:02:44.777 回答
2

简短的回答是否定的,它不会扩展!

长答案

让我们先看看可扩展性。我采用wikipedia提出的定义:“可扩展性是系统、网络或流程以优雅的方式处理不断增长的工作量的能力,或者能够扩大以适应这种增长的能力。”

万一您的某个进程消耗的 CPU 与调度程序授予的 CPU 一样多(有关 linux 调度程序的更多详细信息),您的系统将无法以“优雅的方式”扩展!因此,可扩展性需要的是上面 Ricardo Tomasi 提出的设置,其中每个匹配项都需要它自己的 VM。但这并不优雅,考虑到成本,这不是可行的解决方案。

您的系统无法扩展的问题在于其背后的算法,没有架构可以解决这个问题,但需要修复算法。

您修复算法的选项

  • 尝试在游戏循环中使用一些阻塞机制
  • 检测无限循环的计数器
  • 构建一个具有有限槽的事件队列,以便添加额外的事件将引发异常
  • 以某种方式为您的游戏循环使用时隙算法,就像每场比赛可以消耗一个 node.js 进程的 1/count(matches) 时间(但避免构建自己的调度程序)

即使你的算法是固定的,为每场比赛生成一个进程也会消耗你有限的 RAM 资源的一些 MB,这在可扩展性的意义上是不优雅的。

于 2011-11-23T05:00:20.817 回答
1

我认为actor模型绝对应该提供可扩展性:

  • 使用具有负载平衡机制的进程池
  • 使用ZeroMQ或类似的东西来交换消息
    • 您将需要一些沟通渠道
    • 使用请求/响应进行握手和控制
    • 您可以对主频道使用多播
    • 如果您也有特定用途,您也可以使用发布/订阅

您可能需要一个主进程来平衡和控制所有进程、跟踪事件等。使用参与者模型,您可以跨机器网络横向扩展,实际上您甚至可以拥有对等集群如果您愿意,可能需要使用 RSA 密钥进行身份验证。我建议从等待进程连接的单个主控器开始,实现工作人员骨架并查看如何实现事物的控制端。对于初学者,坚持掌握 2 名工人,调试起来更简单。

对于 Web 前端,您还可以使用代理,例如Nginx,它会调用主服务器,然后主服务器会告诉它将新客户端引导到哪里。我想您需要实现一个 UI 模块,然后在工作人员中使用它。我的意思是 master 不会显示 UI,你的 worker 会监听不同的端口,尽管Nginx会将它隐藏在用户之外(他不会在 URL 栏中看到任何端口),你也可以在上面实现一个 RESTful API那个也是。

于 2011-11-24T11:57:28.300 回答
0

这是一个很难回答的问题,因为我们不知道你的游戏是做什么的......

如果它崩溃,所有游戏都会崩溃,所以我认为拥有多个进程是个好主意。

但我没有看到任何其他充分理由说明你应该有多个进程。(可能有大量的阻塞操作,比如巨大的数据库事务、处理巨大的文件......等等)

就像@Samyak Bhuta 所说,您可以使用 forever 或 cluster 来重新启动您的流程。我们为此使用监视器

于 2011-11-09T02:38:32.467 回答
0

这里有很多事情要讨论。

有多少玩家可以连接到一场比赛?

你用的是什么类型的数据库?它有快速写入吗?

重新启动进程是最后的解决方案,因为如果您有一个游戏,一切都应该快速发生并且您重新启动该进程,那么玩家将需要几秒钟才能重新连接到它。

我不认为每次匹配一个进程是可扩展的,例如,当您同时有 50.000 个匹配时会发生什么?我想说一个更好的解决方案是通过 2 个标准对子进程的匹配进行分组:
a)通过匹配 id(某种分片算法)
b)如果越来越多的玩家出现旋转另一个进程(甚至更多),基于玩家的数量。

在对游戏进行一些测试之前,真的很难决定要做什么。您应该真正测试它以查看它在几个真实匹配项中的表现(它“吃掉”多少 CPU、内存)并根据数据进行一些分析。没有人能准确地说出在这种情况下该怎么做,因为这取决于项目。

于 2011-11-18T08:40:09.080 回答