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

时间:2009-03-31 05:06:04

标签: java sockets c10k

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

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

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

9 个答案:

答案 0 :(得分:11)

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

答案 1 :(得分:7)

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

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

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

答案 2 :(得分:6)

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

答案 3 :(得分:4)

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

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

答案 4 :(得分:2)

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

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

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

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

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

答案 5 :(得分:1)

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


修改

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

答案 6 :(得分:1)

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

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

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

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

这应该更容易扩展。

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

你必须找出你的应用程序在10000个线程失败的原因。

  1. JVM或操作系统中的线程数是否有硬限制?如果是的话,可以解除吗?

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

  3. 还有别的吗?修复它。

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

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