这是问题描述 我们有数千台设备(大约4k-5k),我们必须每2分钟或30秒连续读取数据。每个设备都有其独特的IP。 将收集此数据,然后将其存储在数据库中。这些设备位于全国各地的100个位置。 数据不会24X7读取,但至少12小时。
有一个Web应用程序会在某个时刻请求显示通过这些设备收集数据的数据。 我们知道正在请求设备的数据。
这就是我们认为可以用Java实现的方式
解决方案A : 在每个位置,指定一台将充当服务器的机器,并从x个设备读取数据。此数据将每1小时推送到中央服务器。 在这个指定的机器上,数据被拉出并存储在本地(平面文件或内存数据库)
在这种情况下,我们将拥有与位置数量一样多的服务器。例如,我们可能最终拥有1500台服务器/机器管理,这将成为一场噩梦。
解决方案B :
我们有8-10个中央服务器,每个服务器从一堆机器读取数据。数据排队并按照它到达的顺序被选中。
服务器将数据推送到数据库。
客户如何获取数据?
在解决方案B中,客户端从数据库获取它,假设数据已被推送到数据库并且仍未排队。
您认为应该做得更好?
任何替代设计/解决方案?
我们是否应考虑使用Unix / Perl在服务器上进行编程。我们不想出于其他原因使用C ++。
答案 0 :(得分:4)
您的问题中陈述的要求并不意味着1000个并发连接,因为您可以轻松地每30秒重新建立一次连接。假设连接可以在500毫秒内处理掉,那就留下了5000/30 * 0.5~ = 100个并发连接。任何体面的操作系统都应该能够处理那么多。如此低的并发性,您甚至可以使用单个服务器,每个连接由专用线程处理。
因此,您的设计应该专注于您的其他要求。一些想法:
答案 1 :(得分:3)
如果保持连接,则应该能够在每个连接的20微秒内轮询每个连接。这意味着您可以在100毫秒内轮询每个连接,只需一个非阻塞线程。 (也许是效率最低的方式)
使用选择器是一种更好的方法,因为它提供了一组就绪连接。
如果每次都创建一个新连接,这要花费更多,但可能需要20毫秒(更长时间取决于网络的延迟)。要在30秒内汇集5000个连接,您需要随时保持3-4个活动状态。 (大部分时间都花在建立和销毁连接上)你可以用一个线程完成所有这些,但使用一个小线程池可能更简单。
答案 2 :(得分:2)
尝试Netty。
答案 3 :(得分:2)
如果有可能我认为您的客户端应该发送JMS消息或某种队列,那么您将处理队列以存储在数据库中。有ActiveMQ可以很好地为此工作。如果您喜欢基于云的部署,那么还有SQS(来自亚马逊),那么与主数据库通信的Java服务器可以从中获取。
答案 4 :(得分:1)
您没有提到让客户端与服务器通信,而不是反之亦然。这是一个选择吗?您没有提到正在传输的数据量。
您提到的数字对于Java服务器(具有适当的连接池等)听起来并不合理。尝试对一些解决方案进行原型设计,以测试通信和线程/连接池。并查看Apache Mina等框架。