这是和以前一样的问题:
我在问我是否应该为我的 node.js 游戏在每场比赛中使用一个子进程。
但是我意识到以前我忽略了一些非常重要的细节。
游戏允许玩家以某些有限的方式操纵游戏规则。然而,这仍然会导致无限循环/内存泄漏/停顿和崩溃。
每场比赛 1 个流程是可扩展/合理的想法吗?
这是和以前一样的问题:
我在问我是否应该为我的 node.js 游戏在每场比赛中使用一个子进程。
但是我意识到以前我忽略了一些非常重要的细节。
游戏允许玩家以某些有限的方式操纵游戏规则。然而,这仍然会导致无限循环/内存泄漏/停顿和崩溃。
每场比赛 1 个流程是可扩展/合理的想法吗?
如果任何一个游戏进程都可以吃掉所有的内存或 CPU,那么这是不可扩展的。如果您的服务器是 8 核机器,则八个游戏可能会占用所有 CPU 时间,您无能为力,除了通过监视进程top
并根据需要杀死它们 - 但这会使服务器变得颠簸。
现在,如果您首先设法阻止这些事情(对我来说听起来是一个更好的主意),那么它是可行的。每个进程将占用 30mb 以上的内存,因此每几百个进程就需要一个强大的服务器。以http://site.nodester.com为例,它们似乎在一台机器上运行了大约 600 个进程。他们的软件堆栈也是开源的:https ://github.com/nodester/nodester
node v0.8将带来Isolates (无共享线程),这可能会比子进程使用更少的资源。
一个更“严肃”的解决方案是使用某种虚拟化,如OpenVZ,它允许您设置资源限制,然后只保留一个可用的虚拟服务器池,每个游戏都有自己的。它并不像看起来那么重,每台服务器的开销约为 18mb,每台机器可以托管数百个,尽管它的设置要复杂得多。
简短的回答是否定的,它不会扩展!
长答案
让我们先看看可扩展性。我采用wikipedia提出的定义:“可扩展性是系统、网络或流程以优雅的方式处理不断增长的工作量的能力,或者能够扩大以适应这种增长的能力。”
万一您的某个进程消耗的 CPU 与调度程序授予的 CPU 一样多(有关 linux 调度程序的更多详细信息),您的系统将无法以“优雅的方式”扩展!因此,可扩展性需要的是上面 Ricardo Tomasi 提出的设置,其中每个匹配项都需要它自己的 VM。但这并不优雅,考虑到成本,这不是可行的解决方案。
您的系统无法扩展的问题在于其背后的算法,没有架构可以解决这个问题,但需要修复算法。
您修复算法的选项
即使你的算法是固定的,为每场比赛生成一个进程也会消耗你有限的 RAM 资源的一些 MB,这在可扩展性的意义上是不优雅的。
我认为actor模型绝对应该提供可扩展性:
您可能需要一个主进程来平衡和控制所有进程、跟踪事件等。使用参与者模型,您可以跨机器网络横向扩展,实际上您甚至可以拥有对等集群如果您愿意,可能需要使用 RSA 密钥进行身份验证。我建议从等待进程连接的单个主控器开始,实现工作人员骨架并查看如何实现事物的控制端。对于初学者,坚持掌握 2 名工人,调试起来更简单。
对于 Web 前端,您还可以使用代理,例如Nginx,它会调用主服务器,然后主服务器会告诉它将新客户端引导到哪里。我想您需要实现一个 UI 模块,然后在工作人员中使用它。我的意思是 master 不会显示 UI,你的 worker 会监听不同的端口,尽管Nginx会将它隐藏在用户之外(他不会在 URL 栏中看到任何端口),你也可以在上面实现一个 RESTful API那个也是。
这是一个很难回答的问题,因为我们不知道你的游戏是做什么的......
如果它崩溃,所有游戏都会崩溃,所以我认为拥有多个进程是个好主意。
但我没有看到任何其他充分理由说明你应该有多个进程。(可能有大量的阻塞操作,比如巨大的数据库事务、处理巨大的文件......等等)
就像@Samyak Bhuta 所说,您可以使用 forever 或 cluster 来重新启动您的流程。我们为此使用监视器
这里有很多事情要讨论。
有多少玩家可以连接到一场比赛?
你用的是什么类型的数据库?它有快速写入吗?
重新启动进程是最后的解决方案,因为如果您有一个游戏,一切都应该快速发生并且您重新启动该进程,那么玩家将需要几秒钟才能重新连接到它。
我不认为每次匹配一个进程是可扩展的,例如,当您同时有 50.000 个匹配时会发生什么?我想说一个更好的解决方案是通过 2 个标准对子进程的匹配进行分组:
a)通过匹配 id(某种分片算法)
b)如果越来越多的玩家出现旋转另一个进程(甚至更多),基于玩家的数量。
在对游戏进行一些测试之前,真的很难决定要做什么。您应该真正测试它以查看它在几个真实匹配项中的表现(它“吃掉”多少 CPU、内存)并根据数据进行一些分析。没有人能准确地说出在这种情况下该怎么做,因为这取决于项目。