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 多人游戏多线程和多核的主要内容,如果未能解决你的问题,请参考以下文章