我正在编写一个简单的多线程socketserver,我想知道如何最好地处理传入连接:
为每个新连接创建一个新线程。通过指定backlog
将所有传入连接添加到队列中,并拥有一个处理队列的工作线程池
我倾向于选择2,因为我真的不想拒绝任何连接,即使在高负荷下也是如此,但我想知道是否有任何考虑我应该注意接受有效的无限连接?
答案 0 :(得分:6)
通过无限连接,您可以创建大量线程。这意味着需要进行大量处理,而且默认情况下,每个线程只会为堆使用固定数量的内存(我认为每个线程的数字为512kB ,但这可能与平台有关)。
通过汇集固定数量的线程并接受有限数量的客户端,您将确保在合理的时间段内为您的某些客户提供服务,并且您的服务器不会因超载而崩溃。
您可能需要查看this article on building servers using NIO或查看Apache Mina等框架。
答案 1 :(得分:4)
我真的不想拒绝任何 连接
其实你可能会这样做。当您超载时,您希望保留足够的容量来摆脱当前的负载,然后再接受。让永远陷入停滞的人不再比拒绝连接更可接受。
排队理论认为最佳点是利用率约为70%。如果你的服务器的稳定负载高于硬件的速度,那么硬件的速度会更快。
话虽如此,如果您期待数十万个连接,我会使用线程池或NIO。如果你只期望数千,那么每个连接的线程是最简单的方法。
答案 2 :(得分:2)
如果您接受无限制的连接,并且您的处理速度不足以应对传入连接流,那么您的队列将会填满 - 直到它到达某个点,处理先前的请求需要很长时间,大多数一旦你找到它们,请求就不再对答案感兴趣了。
答案 3 :(得分:2)
答案 4 :(得分:0)
我真的不想拒绝任何连接,即使在高负荷下也是如此
您的选项2是我认为的唯一方法。每个5-10k连接应该有一个固定的NIO选择器线程。但是没有什么可以延迟这个关键线程,所以你使用DEMUX在固定数量的固定线程而不是线程池之间分配工作。还有一个MUX来收集工作并回复客户。正如EJP所说,如果您的工作线程滞后,最终您将不得不断开连接,除非您开始将消息转储到磁盘以使您的队列尽可能大。这样,即使在高负载下,y也不会丢弃任何连接。您可以查看详细解释的this article和下图:
免责声明:我是CoralQueue的开发者之一