每个连接模型的Java线程与NIO

Kev*_*Jin 37 java multithreading asynchronous nio nonblocking

非阻塞Java NIO是否仍然比每个连接异步套接字的标准线程慢?

另外,如果你每个连接使用线程,你会创建新线程还是使用非常大的线程池?

我正在用Java编写一个MMORPG服务器,它应该能够在足够强大的硬件下轻松扩展10000个客户端,尽管最大客户端数量是24000(我相信由于15000线程,每个连接模型的线程无法达到Java中的限制).从一篇三年前的文章中,我听说用每个连接模式的线程阻塞IO仍然比NIO快25%(即本文档http://www.mailinator.com/tymaPaulMultithreaded.pdf),但是可以在这一天还能实现吗?从那以后Java发生了很大变化,我听说在比较现实生活场景时结果是有问题的,因为使用的VM不是Sun Java.另外,因为它是一个MMORPG服务器,许多并发用户互相交互,所以使用同步和线程安全实践会降低性能,以至于为10000个客户端提供服务的单线程NIO选择器会更快吗?(所有工作都不必在带有选择器的线程上处理,它可以在工作线程上处理,就像MINA/Netty的工作方式一样).

谢谢!

irr*_*ble 21

NIO的好处应该是一粒盐.

在HTTP服务器中,大多数连接是保持活动连接,它们大多数时间都处于空闲状态.为每个预先分配线程将浪费资源.

对于MMORPG来说,事情是非常不同的.我猜连接总是忙于接收用户的指令并向用户发送最新的系统状态.大多数时候需要一个线程来进行连接.

如果您使用NIO,则必须不断为连接重新分配线程.对于简单的每线程固定线程解决方案,它可能是一个较差的解决方案.

默认的线程堆栈大小相当大(1/4 MB?),这是为什么只能有限的线程的主要原因.尝试减少它,看看你的系统是否可以支持更多.

但是,如果您的游戏确实非常"忙碌",那么您最需要担心的是CPU.NIO与否,在机器上处理成千上万的超级活跃游戏玩家真的很难.


Jay*_*Jay 12

实际上有3种解决方案:

  1. 多线程
  2. 一个线程和NIO
  3. 解决方案1和2同时进行

对性能而言,最好的办法是在NIO通过网络传入新消息时,在这些线程上使用少量有限数量的线程和多路复用网络事件.


将NIO与一个线程一起使用是一个坏主意,原因如下:

  • 如果您有多个CPU或核心,则您将闲置资源,因为如果您只有一个线程,则一次只能使用一个核心.
  • 如果由于某种原因(可能要进行磁盘访问)而必须阻塞,那么当您在等待磁盘时可以处理另一个连接时,CPU处于空闲状态.

每个连接一个线程是一个坏主意,因为它不能扩展.让我们说:

  • 10 000个连接
  • 2个CPU,每个2核
  • 在任何给定时间只会阻止100个线程

然后你可以计算出你只需要104个线程.更多,你浪费资源管理你不需要的额外线程.管理10000个线程需要大量的簿记.这会减慢你的速度.


这就是你结合这两种解决方案的原因.此外,请确保您的VM使用最快的系统调用.每个操作系统都有自己独特的系统调用,用于高性能网络IO.确保您的VM使用最新且最好的.我相信这是Linux中的epoll().

另外,如果你每个连接使用线程,你会创建新线程还是使用非常大的线程池?

这取决于您希望花费多少时间进行优化.最快的解决方案是在需要时创建线程和字符串等资源.然后让垃圾收集在你完成它们时声明它们.您可以通过拥有一个资源池来提升性能.您不需要创建新对象,而是要求池中的一个,并在完成后将其返回池中.这增加了并发控制的复杂性.这可以通过非阻塞算法等高级并发算法进一步优化.新版本的Java API为您提供了一些新功能.您可以在一个程序中度过余生,进行这些优化.什么是您的特定应用程序的最佳解决方案可能是一个值得自己发布的问题.


Pet*_*rey 9

如果您愿意在功能强大的硬件上花费任何金钱,那么为什么要将自己限制在一台服务器上.谷歌不使用一台服务器,他们甚至不使用一个服务器数据中心.

一个常见的误解是NIO允许非阻塞IO,因此它是唯一值得基准测试的模型.如果您对阻止NIO进行基准测试,则可以比旧IO快30%.即如果您使用相同的线程模型并仅比较IO模型.

对于复杂的游戏,在达到10K连接之前,你更有可能耗尽CPU.同样,有一个水平扩展的解决方案更简单.然后,您无需担心可以获得多少连接.

有多少用户可以合理地互动?24?在这种情况下,您有1000个独立的组进行交互.您将不会在一台服务器中拥有这么多核心.

您打算在服务器上花费多少钱?您可以以低于5000英镑的价格购买带有64 GB内存的12核服务器.如果您在此服务器上放置2500个用户,则每个用户花费2英镑.

编辑:我有一个参考http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html这是我的.;)我是由Java Networking GURU的人审核过的,并且广泛同意他所发现的内容.