Java socketserver:如何处理许多传入连接?

时间:2010-03-17 22:05:45

标签: java multithreading sockets connection

我正在编写一个简单的多线程socketserver,我想知道如何最好地处理传入连接:

  1. 为每个新连接创建一个新线程。通过指定backlog

  2. ,可以限制并发线程数并限制等待连接
  3. 将所有传入连接添加到队列中,并拥有一个处理队列的工作线程池

  4. 我倾向于选择2,因为我真的不想拒绝任何连接,即使在高负荷下也是如此,但我想知道是否有任何考虑我应该注意接受有效的无限连接?

5 个答案:

答案 0 :(得分:6)

通过无限连接,您可以创建大量线程。这意味着需要进行大量处理,而且默认情况下,每个线程只会为堆使用固定数量的内存(我认为每个线程的数字为512kB ,但这可能与平台有关)。

通过汇集固定数量的线程并接受有限数量的客户端,您将确保在合理的时间段内为您的某些客户提供服务,并且您的服务器不会因超载而崩溃。

您可能需要查看this article on building servers using NIO或查看Apache Mina等框架。

答案 1 :(得分:4)

  

我真的不想拒绝任何   连接

其实你可能会这样做。当您超载时,您希望保留足够的容量来摆脱当前的负载,然后再接受。让永远陷入停滞的人不再比拒绝连接更可接受。

排队理论认为最佳点是利用率约为70%。如果你的服务器的稳定负载高于硬件的速度,那么硬件的速度会更快。

话虽如此,如果您期待数十万个连接,我会使用线程池或NIO。如果你只期望数千,那么每个连接的线程是最简单的方法。

答案 2 :(得分:2)

如果您接受无限制的连接,并且您的处理速度不足以应对传入连接流,那么您的队列将会填满 - 直到它到达某个点,处理先前的请求需要很长时间,大多数一旦你找到它们,请求就不再对答案感兴趣了。

答案 3 :(得分:2)

每个连接1个线程无法扩展。在C10K问题上阅读相关内容。这是一个很长的阅读,但很有名。

我建议您了解NIO或者使用令人印象深刻的netty框架来处理所有繁重的工作(NIO)。

答案 4 :(得分:0)

  

我真的不想拒绝任何连接,即使在高负荷下也是如此

您的选项2是我认为的唯一方法。每个5-10k连接应该有一个固定的NIO选择器线程。但是没有什么可以延迟这个关键线程,所以你使用DEMUX在固定数量的固定线程而不是线程池之间分配工作。还有一个MUX来收集工作并回复客户。正如EJP所说,如果您的工作线程滞后,最终您将不得不断开连接,除非您开始将消息转储到磁盘以使您的队列尽可能大。这样,即使在高负载下,y也不会丢弃任何连接。您可以查看详细解释的this article和下图:

enter image description here

免责声明:我是CoralQueue的开发者之一