8

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

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

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

4

9 回答 9

11

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

于 2009-03-31T05:25:41.663 回答
8

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

Glassfish 应用服务器的Grizzly组件是更具可扩展性的开源 NIO 应用程序之一。Jean-Francois Arcand撰写了许多关于他在该项目上的工作的信息丰富、深入的博客文章,并涵盖了使用 NIO 编写此类软件时的许多细微缺陷。

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

于 2009-03-31T05:25:08.500 回答
6

NIO 的好处是值得商榷的。请在此处此处查看 Paul Tyma 的博客条目。

于 2009-03-31T16:08:16.143 回答
4

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

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

于 2009-03-31T05:26:47.513 回答
2

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

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

也就是说,众所周知,NIO 在您第一次实施时很难做到 100% 正确。

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

(Naga 来源也恰好可以在不注明原作者的情况下自由修改或复制)

于 2009-04-01T20:55:01.470 回答
1

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

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

您创建一个包含 50 个线程的线程池。

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

这应该更容易扩展。

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

于 2009-03-31T16:04:56.120 回答
1

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


编辑

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

于 2009-03-31T05:24:47.877 回答
0

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

于 2009-07-02T16:40:43.043 回答
0

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

  1. JVM 或操作系统中的线程数是否有硬性限制?如果是这样,它可以被取消吗?

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

  3. 还有什么?修理它。

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

您也可以考虑 NIO,但我认为它也可以与线程一起正常工作。

于 2012-03-24T13:02:55.117 回答