为什么我的Perl TCP服务器脚本会挂起许多TCP连接?

时间:2010-04-19 17:45:27

标签: c linux perl sockets tcp

我接受TCP连接的服务器有一个奇怪的问题。即使通常有一些进程在等待,但在某些连接数量上它会挂起。

长版:

服务器是用Perl编写的,并使用重用标志绑定$srv套接字并监听== 5.然后,它分为10个进程,循环为$clt=$srv->accept(); do_processing($clt); $clt->shutdown(2);

用C语言编写的客户端也非常简单 - 它发送一些行,然后接收所有可用的行并执行shutdown(sockfd, 2);没有任何异步正在进行,最后发送和接收队列都是空的(如报告的那样) netstat)。

连接仅持续约20ms。所有客户端的行为方式相同,实现方式相同等等。现在假设我接受来自客户端1的X连接和来自客户端2的另一个X。进程仍然报告它们都是空闲的时间。如果我从客户端3添加另一个X连接,突然服务器进程在接受后立即开始挂起。他们在accept();之后执行的第一个阻止事件是while (<$clt>) ... - 但是他们没有获得任何数据(在第一次尝试时已经存在)。突然间,所有10个进程都处于此状态,并且不会停止等待。在strace上,服务器进程似乎挂在read()上,这是有道理的。

属于该服务器的TIME_WAIT状态中存在大量连接(问题开始显示时为~100),但这可能是一个红色的鲱鱼。

这里可能会发生什么?


经过一些更多的分析:结果发现客户端有问题,在尝试下一个连接之前没有正确关闭先前的连接。负载平衡列表开头的服务器是旧的连接。

2 个答案:

答案 0 :(得分:1)

这可能不是您问题的解决方案,但它可能会解决您将来遇到的问题:完成后不要忘记关闭()套接字! shutdown()将断开流,但它仍然会吃掉文件描述符。

由于你说strace显示进程停留在read()中,那么你的问题似乎是客户端没有发送你希望它发送的数据。您应该修复您的客户端,或者向您的服务器进程添加一个警报(),以便它们能够在死客户端中生存。

答案 1 :(得分:0)

是否会飙升然后暂停很长时间(大约两分钟左右)然后再次激增?如果是这样,您可能没有将系统最大打开文件限制设置得足够高。