如何在Java中同时与1000个套接字进行通信?

时间:2010-10-06 20:12:29

标签: java sockets

这是问题描述 我们有数千台设备(大约4k-5k),我们必须每2分钟或30秒连续读取数据。每个设备都有其独特的IP。 将收集此数据,然后将其存储在数据库中。这些设备位于全国各地的100个位置。 数据不会24X7读取,但至少12小时。

有一个Web应用程序会在某个时刻请求显示通过这些设备收集数据的数据。 我们知道正在请求设备的数据。

这就是我们认为可以用Java实现的方式

解决方案A : 在每个位置,指定一台将充当服务器的机器,并从x个设备读取数据。此数据将每1小时推送到中央服务器。 在这个指定的机器上,数据被拉出并存储在本地(平面文件或内存数据库)

在这种情况下,我们将拥有与位置数量一样多的服务器。例如,我们可能最终拥有1500台服务器/机器管理,这将成为一场噩梦。

解决方案B

我们有8-10个中央服务器,每个服务器从一堆机器读取数据。数据排队并按照它到达的顺序被选中。

服务器将数据推送到数据库。

客户如何获取数据

在解决方案B中,客户端从数据库获取它,假设数据已被推送到数据库并且仍未排队。

您认为应该做得更好?

任何替代设计/解决方案?

我们是否应考虑使用Unix / Perl在服务器上进行编程。我们不想出于其他原因使用C ++。

5 个答案:

答案 0 :(得分:4)

您的问题中陈述的要求并不意味着1000个并发连接,因为您可以轻松地每30秒重新建立一次连接。假设连接可以在500毫秒内处理掉,那就留下了5000/30 * 0.5~ = 100个并发连接。任何体面的操作系统都应该能够处理那么多。如此低的并发性,您甚至可以使用单个服务器,每个连接由专用线程处理。

因此,您的设计应该专注于您的其他要求。一些想法:

  • 设备是否有防火墙?使用解决方案A,您将从每个位置获得传出连接,使用解决方案B,您将拥有传入的连接。
  • 您需要什么样的可靠性?例如,如果某个位置的互联网连接断开,您是否需要记录测量值?这意味着本地服务器会缓冲测量结果。

答案 1 :(得分:3)

如果保持连接,则应该能够在每个连接的20微秒内轮询每个连接。这意味着您可以在100毫秒内轮询每个连接,只需一个非阻塞线程。 (也许是效率最低的方式)

使用选择器是一种更好的方法,因为它提供了一组就绪连接。

如果每次都创建一个新连接,这要花费更多,但可能需要20毫秒(更长时间取决于网络的延迟)。要在30秒内汇集5000个连接,您需要随时保持3-4个活动状态。 (大部分时间都花在建立和销毁连接上)你可以用一个线程完成所有这些,但使用一个小线程池可能更简单。

答案 2 :(得分:2)

尝试Netty

答案 3 :(得分:2)

如果有可能我认为您的客户端应该发送JMS消息或某种队列,那么您将处理队列以存储在数据库中。有ActiveMQ可以很好地为此工作。如果您喜欢基于云的部署,那么还有SQS(来自亚马逊),那么与主数据库通信的Java服务器可以从中获取。

答案 4 :(得分:1)

您没有提到让客户端与服务器通信,而不是反之亦然。这是一个选择吗?您没有提到正在传输的数据量。

您提到的数字对于Java服务器(具有适当的连接池等)听起来并不合理。尝试对一些解决方案进行原型设计,以测试通信和线程/连接池。并查看Apache Mina等框架。