Java套接字编程不适用于10,000个客户端

我可以创建多个线程来支持套接字编程中的多客户端function; 这工作正常。 但是如果要连接10,000个客户端,我的服务器就无法创建这么multithreading。

如何管理线程以便我可以同时收听所有这些客户端?

此外,如果在这种情况下服务器想要向特定客户端发送内容,那么它怎么可能呢?

您应该研究Java的NIO(“新I / O”)库以进行非阻塞网络编程。 NIO旨在精确解决您所面临的服务器可扩展性问题!

  • 关于NIO的介绍性文章: 使用Java NIO构建高度可扩展的服务器
  • 摘自O’Reilly的Java NIO书

Java中高度可扩展的套接字编程需要“新I / O”或NIO包中提供的可选择通道 。 通过使用非阻塞IO,单个线程可以为许多套接字提供服务,仅适用于那些准备就绪的套接字。

其中一个可扩展的开源NIO应用程序是Glassfish应用程序服务器的Grizzly组件。 Jean-Francois Arcand撰写了许多关于他在该项目上的工作的内容丰富的博客文章,并介绍了使用NIO编写此类软件时的许多微妙缺陷。

如果非阻塞IO的概念对您来说是新的,使用像Grizzly这样的现有软件,或者至少使用它作为适应的起点,可能会非常有帮助。

NIO的好处值得商榷。 请参阅Paul Tyma的博客文章。

每个连接线程的线程模型(阻塞套接字I / O)不能很好地扩展。 以下是Java NIO的介绍,它允许您在java中使用非阻塞套接字调用: http : //today.java.net/cs/user/print/a/350

正如文章所述,有很多框架可用,所以你不必自己动手。

如前所述,10.000客户并不容易。 对于java,NIO(可能使用单独的线程池扩充以处理每个请求而不阻塞NIO线程)是处理大量客户端的常用方法。

如上所述,根据实现,线程实际上可能会扩展,但它在很大程度上取决于客户端连接之间的交互量。 如果线程之间几乎没有同步,则大规模线程更有可能工作。

也就是说,NIO在第一次实施时非常难以100%正确。

我建议你尝试一下,或者至少在naga.googlecode.com上查看Naga NIO lib的源代码。 与大多数其他NIO框架相比,lib的代码库很小。 您应该能够快速实施测试,看看是否可以启动并运行10.000个客户端。

(Naga来源也可以自由修改或复制而不归咎于原作者)

这不是一个简单的问题,但是非常深入(抱歉,不是在java中),答案请看: http : //www.kegel.com/c10k.html


编辑

即使使用nio,这仍然是一个难题。 即使您使用非阻塞套接字,10000连接也是计算机上的巨大资源负担。 这就是大型网站拥有服务器场和负载平衡器的原因。

为什么不一次只处理一定数量的请求。

假设您希望一次最多处理50个请求(不创建太multithreading)

您创建50个线程的线程池。

您将所有请求放入队列(接受连接,保持套接字打开),每个线程完成后,获取下一个请求然后处理它。

这应该更容易扩展。

此外,如果需要,将更容易进行负载平衡,因为您可以共享多个服务器的队列

我个人宁愿使用创建自定义I / O非阻塞设置,例如使用一个线程接受客户端并使用另一个线程来处理它们(检查是否有任何输入可用并在必要时将数据写入输出)。

您必须弄清楚为什么您的应用程序在10,000个线程中失败。

  1. JVM或OS中的线程数是否存在硬限制? 如果是这样,可以取消吗?

  2. 你的内存不足吗? 尝试为每个线程配置较小的堆栈大小,和/或向服务器添加更多内存。

  3. 别的什么? 修理它。

只有在确定问题的根源后,您才能解决问题。 理论上10,000个线程应该没问题但是在这个并发级别,如果你希望它能够解决,它需要对JVM和操作系统进行一些额外的调整。

您也可以考虑NIO,但我认为它也适用于线程。

Interesting Posts