【问题标题】:Java socketserver: How to handle many incoming connections?Java socketserver:如何处理许多传入连接?
【发布时间】:2011-01-28 19:17:48
【问题描述】:

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

  1. 为每个新连接创建一个新线程。通过指定积压限制并发线程数和等待连接数

  2. 将所有传入连接添加到队列中,并拥有一个处理队列的工作线程池

我倾向于选择选项 2,因为我真的不想拒绝任何连接,即使在高负载下也是如此,但我想知道在接受有效的无限制连接时是否有任何注意事项?

【问题讨论】:

    标签: java multithreading sockets connection


    【解决方案1】:

    通过无限连接,您可能会创建大量线程。这意味着需要大量处理,而且默认情况下,每个线程仅会为堆消耗固定数量的内存(我认为这个数字是 512kB 每个线程,但这可能取决于平台)。

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

    您可能想查看this article on building servers using NIO 或查看诸如Apache Mina 之类的框架。

    【讨论】:

    • 作为一个(我假设是固定大小的)线程池正在被使用,线程的数量不会是无限的,而是受限于池的大小。
    • 抱歉 - 我认为我通过写“轮询”而不是“池”来混淆问题
    • 谢谢 - Apache Mina 非常棒,正是我想要的!
    【解决方案2】:

    我真的不想拒绝任何 连接

    实际上你可能会这样做。当您超载时,您希望保留足够的容量来摆脱当前的负载,然后再接受更多。让每个人都停下来比拒绝联系更可接受。

    排队理论表明,最佳使用率约为 70%。如果您的服务器将有高于此的稳定负载,请获得更快的硬件,直到它没有。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        每个连接的 1 个线程无法扩展。在C10K 问题中了解它。读起来很长,但很有名。

        我建议了解 NIO 或者使用令人印象深刻的 netty 框架,它可以为您处理所有繁重的 (NIO)。

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-11-20
            • 2015-04-15
            • 2019-10-10
            • 2012-12-01
            • 2016-06-18
            • 1970-01-01
            • 2015-04-21
            • 2014-05-27
            相关资源
            最近更新 更多