每个连接的线程与 java 中所有连接的一个线程

Thread per connection vs one thread for all connections in java

我目前有两种不同类型的服务器和客户端在工作,我正在尝试确定哪一种更适合 MMO 服务器,或者至少是一次至少有 100 名玩家的小型 MMO 服务器。

我的第一台服务器使用每个连接模型一个线程,并使用 ObjectOutputStream 通过套接字发送对象。

我的第二台服务器使用 java nio 只对所有连接使用一个线程,并使用 select 循环遍历它们。此服务器也在使用 ObjectOutputStream 发送数据

对于我的问题,MMO 服务器的更好方法是什么?如果单线程模型更好,那么通过套接字通道发送对象会受到怎样的影响,它会不会一直被读取而不是得到完整的对象?

对于通过它发送的每个对象,它只包含一个整数和 2 个浮点数,用于发送位置和玩家 ID。

我会将这个问题与为什么 MMO 使用 UDP 而不是 TCP 联系起来。原因是 UDP 承诺快速交付,而 TCP 承诺保证交付。

类似的类比可以应用于您选择的单线程与多线程 model.Regardless,您的整体 CPU 周期保持不变,即服务器只能处理这么多每秒信息。 让我们看看在每种情况下会发生什么

1.单线程模型: 在这种情况下,您自己的实现或底层库将最终创建一个请求开始排队的管道。如果您处于最小负载,队列实际上将保持为空并且执行将是实时的,但是可能会浪费很多 CPU。在最大负载下,将会有一个很长的队列,并且随着负载的增加执行会有延迟,但是交付将得到保证并且 CPU 利用率将是最佳的。通常一个缓慢的客户端会拖慢其他人的速度。

  1. 多线程模型: 在这种情况下,根据您自己的实现或底层库如何实现多线程,请求的并行执行将开始发生。 MT 的问题在于它很容易被愚弄。例如,java.util.concurrent.ThreadPoolExecutor 实际上不会进行任何并行处理,除非您将队列大小设置为较低的值。一旦并行处理开始发生,在最小负载下,您的执行速度将超快,CPU 利用率将达到最佳,游戏性能将非常出色。但是,在最大负载下您的 RAM 使用率会很高并且 CPU 利用率仍然是最佳的。通常,您需要设置线程中断以避免慢速客户端占用所有线程,这意味着慢速客户端的性能会出现故障。此外,当您开始耗尽线程池和资源时,线程将排队或被丢弃,从而导致性能出现问题。

在游戏中,性能比稳定性更重要,因此毫无疑问,您应该尽可能使用 MT,但是调整线程参数以补充服务器资源将决定它是好是坏