繁体   English   中英

具有内部数据交换的服务器应用程序的工作线程与节点集群

[英]Worker threads vs node cluster for server application with internal data exchange

我知道像这样的问题可能是见仁见智的问题,这就是为什么我试图提供更多细节。

我正在开发具有以下“功能”的 WebSocket 服务器应用程序:

  • 2-3个连接可以指向同一个用户
  • 用户偶尔可以相互交流。 突发或连续交换数据
  • 全球数据的一部分应该始终在所有用户之间同步
  • 一部分全球数据应该在一些用户之间延迟(按需)同步

我想到了 2 种可能的结构:

  1. 工作线程。 主线程处理 all.network IO,connection->User bundling 并存储/与全局数据交互。 它还向工作线程发送大量postMessage -s。 当来自不同线程的 2 个玩家需要交互时,工作线程偶尔会相互交谈。 可能的问题:
    • postMessage开销(据我了解,主要来自序列化)。 理论上,对于大多数消息,我可以尝试使用SharedArrayBuffer 我认为除此之外无法对其进行优化。
    • 主线程将处理 .network IO 和全局数据交互。 也许这会成为一个瓶颈?
  2. 无状态 NodeJS 集群,将所有数据存储在 Redis 中,并偶尔使用锁定。 问题/问题:
    • 会使用更多内存
    • 不管 Redis 有多快,与它通信很可能比使用postMessage -s 慢。
    • 多台服务器真的有用吗? 我听说将同一个类型 IO 拆分成多个进程是个坏主意。 或者至少不像使用本机 Node 异步 IO 那样有益。
    • 我不认为有一种方法可以根据用户 ID 之类的东西来捆绑连接。
    • 根据要求获取和设置 Redis 数据是可以的。 但是一个进程怎么知道某个键是否被另一个进程修改了呢?

听起来您可能正处于设计阶段,还没有可以测量的运行代码。 如果是这种情况,请不要假设您知道瓶颈在哪里,而是花时间设计和实施尚未衡量的问题。 性能瓶颈通常并不在您认为的位置。 花费大量时间实施更复杂的架构来解决您认为可能存在瓶颈的地方,如果您错了,很容易浪费大量开发时间。

相反,实施更简单的架构甚至原型并大规模测试和测量。 找出你真正的瓶颈在哪里。 然后,您将确定您专注于正确的问题,并且将拥有一个测试引擎,您可以在实施替代方案时测量该引擎以查看您的表现如何。

如果您的问题的主要焦点是解决代码中的 CPU 密集型操作,我可能会首先探索使用工作线程和作业队列。 仍然有 webSockets 连接到的一个主要进程,以及您保留所有 state 的位置。

当请求进来时,创建一个作业并将其放入作业队列(作业队列可以只是等待处理的作业对象的数组)。 如果有空闲线程,则从作业队列中获取最旧的作业并将作业发送给该线程。 它会以任何需要的 CPU 密集型方式处理它。 完成后,它将结果发回主线程,主线程将下一个作业发送给它,并对结果做任何需要的事情。

您可以拥有与 CPU 内核一样多的工作线程(多了就会失去效率)。

该架构试图将 CPU 密集型操作本地化并将它们分配给工作线程,同时保持架构的 rest(您的 webSocket 连接和 state 管理)相同,以使事情尽可能简单。

如果 CPU 密集型操作需要访问大量 state,那么您可能希望将 state 移动到一个数据库,该数据库可以管理对 state 的多线程访问(这是一个有用的事情之一)数据库)。 如果 state 不是持久的,则数据库可能是 Redis。这通常优于同步架构,因为在更新 state 时管理并发并以任何通用方式进行同步可能不是您想要自己实现的(这是一个难题)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM