Node.js 多人游戏多线程和多核

Posted

技术标签:

【中文标题】Node.js 多人游戏多线程和多核【英文标题】:Node.js multiplayer game multi threading and multi core 【发布时间】:2019-11-14 16:25:53 【问题描述】:

我正在开发一款网络多人游戏。使用 docker、node、带有 postgres 和 redis 的数字海洋来获取数据。我的 docker 机器有很多 CPU,但 node.js 只使用一个 CPU。正因为如此,我已经接近这个游戏可以扩展的地步了。

我希望能够利用其他 CPU。我听过和读过的一些方法是:

使用子进程 在 1 个 droplet 中运行多个节点服务器 在不同的 Droplet 中运行多个节点服务器

我宁愿不运行更多的节点服务器,如果可以的话。游戏结构是这样的:

大厅(玩家信息、所有在线玩家等) 房间(人数有限) 游戏(玩家数量有限,20-40m 游戏时间)

大厅 房间 => 游戏

我没有测量方法(也可以在这里接受建议),但我猜大部分 CPU 使用率来自单个游戏。我希望有一个解决方案,有点像将 Lobby & Rooms 保留在主线程中。虽然所有游戏都是在随机的不同线程中创建的,或者是在活动游戏数量最少的线程中创建的。

我预见到的一些可能的问题是消息和玩家状态。一个播放器可以同时打开多个浏览器选项卡。这意味着单个玩家对象可以有 4 个会话和套接字连接。 1 个内部大厅,3 个内部游戏。玩家可能想从他的游戏中向大厅内的玩家发送私人消息。此外,当游戏结束时,玩家状态也会更新。

根据所有这些信息,我最好的方法是什么?任何文档、博客、链接、关键字、视频都值得赞赏。

【问题讨论】:

【参考方案1】:

这个问题的典型解决方案是使用 Redis,听起来你已经在这样做了。这个想法是您将游戏服务器编程为“无状态”,这意味着所有状态都存储在 Redis 中。

然后,您可以生成 N 个游戏服务器实例,其中 N 等于您的 VPS 液滴上的 CPU 数量减去 1。(让操作系统有 1 个 CPU 更好。)

这是一个比使用 NodeJS Web Workers 更简洁的解决方案,因为您不必担心 IPC 和进程的生命周期。

此外,更新您的游戏服务器变得非常容易。在内部处理状态的服务器中,当您更新服务器时,您的用户将不得不停机,这意味着他们必须结束他们当前正在玩的任何游戏,以便您可以重新启动所有内容。但是,如果所有状态都在 Redis 中,您可以简单地关闭所有实例并启动新实例,而无需真正停机。

【讨论】:

【参考方案2】:

您是否尝试过 Web Workers?它们允许您在 Node.js 中使用线程,their API 终于稳定了。

您可以在 Rich Trott 的 this blog post 中看到一些示例。

这是一个最小的例子:

const  Worker, isMainThread, parentPort  = require('worker_threads');
if (isMainThread) 
  // This code is executed in the main thread and not in the worker.

  // Create the worker.
  const worker = new Worker(__filename);
  // Listen for messages from the worker and print them.
  worker.on('message', (msg) =>  console.log(msg); );
 else 
  // This code is executed in the worker and not in the main thread.

  // Send a message to the main thread.
  parentPort.postMessage('Hello world!');

【讨论】:

所以当我向工作人员发送东西时,我不必管理它是在 cpu 2 还是 3 上,对吧?它只是自动分配的吗?另外,如果工作人员内部有大量数据怎么办?这会产生问题吗?想想类似 FPS 地图的游戏状态。

以上是关于Node.js 多人游戏多线程和多核的主要内容,如果未能解决你的问题,请参考以下文章

单核和多核,单进程和多进程,单线程与多线程

多线程利用多核,cpu利用率却达不到100%?

“多核多线程技术开放化”官方终于开始做点正事了!

Node.js 多进程

linux单进程如何实现多核cpu多线程分配?

电脑CPU多核数和多线程的区别对比!4核8线程和6核6线程哪个好?