每个客户端模型或 NIO 反应器模式的旧 I/O 线程?

2022-09-03 15:32:49

我正在编写多人游戏的服务器端网络。该游戏是一款RPG游戏,它的绝对最大容量为2000名玩家,但实际上它将达到约300名玩家,尽管它可能更高或更低。在很长一段时间里,每当我不得不做涉及大量客户端的网络时,我都坚持使用NIO,因为它不需要使用数百个线程。最近,我遇到了一个PowerPoint演示文稿,它详细描述了这两个模型,它几乎使每个客户端的线程模型看起来优于NIO。我还发现一些地方,它指出旧的IO实际上也可以优于NIO。

PowerPoint可以在这里找到(它有点旧):http://www.mailinator.com/tymaPaulMultithreaded.pdf

我还没有写过任何内容,所以如果我必须改变我的整个网络设计,那么从头开始对我来说不是一个问题。我没有时间压力。最初,我使用NIO设计一个反应器模式实现(选择一个事件,调度一个处理程序来处理事件)。

更多信息可以在这里找到:http://en.wikipedia.org/wiki/Reactor_pattern

我的整个反应器实现都设计为使用单个线程。由于我读到旧的IO可以超越,它实际上使我陷入了两难境地。我不想设计一个复杂的NIO系统,使用多个线程只是为了充分利用所有的CPU功率,但我也对让单个应用程序使用300多个线程的想法感到畏缩。哪种设计适合我的目的?每个客户端的线程的优点是,它真正利用了所有的CPU能力,但与此同时,它使系统陷入困境。更不用说,单个线程的堆栈大小会占用大量内存(乘以几百倍时)。我应该坚持反应堆模式吗?

我知道这个问题有点模棱两可,但我觉得我需要专门针对我的情况提出一个问题,因为我在这个网站上找不到一个问题,也没有一个网站来解决我的同类问题。有一个关于游戏,但游戏的目的是处理成千上万的玩家。

多谢!如果您需要任何澄清,请询问!


答案 1

我不想设计一个复杂的NIO系统,使用多个线程只是为了充分利用所有的CPU功率,但我也对让单个应用程序使用300多个线程的想法感到畏缩。哪种设计适合我的目的?

我们的JVM以超过500个线程连续运行(现在它们位于约700个),峰值在1000s。我认为没有理由认为800个线程在某种程度上是“畏缩”的。当你达到10,000个线程(作为一个球场数字)时,我会开始担心 - 如果你在32位以下运行,可能会更少。当你进入1000s时,你当然必须分配更多的内存,但任何低于1k线程的东西都应该不是问题。这是一个关于线程创建数字的好页面。

当您有大量与不频繁 IO 的连接时,NIO 最有效。当涉及到异步通信时,它解决了很多问题,从功能的角度来看,“旧IO”无法做到“旧IO”无法做到的事情(例如,可中断通道和非阻塞IO),但是单线程处理程序是一个更简单的模型,我对它可以在许多配置中优于NIO实现并不感到惊讶。使用NIO,您可以在Java代码中执行许多操作,这些操作是在JVM中为您完成的,甚至是本机代码中的内核中完成的。流的多路复用和就绪 IO 的处理都是您使用“旧 IO”模型“免费”(就复杂性而言)获得的东西。

我会保持简单,并坚持使用线程-每个客户端的模式,直到你有充分的理由来承受复杂性的打击。


答案 2