python SocketServer卡在waitpid()系统调用上

时间:2012-10-11 06:41:40

标签: python signals socketserver

我正在使用带有ForkingMixIn的Python(2.7)SocketServer。它运作良好。

然而,有时在大量使用(大量快速连接/断开客户端)时,“服务器”卡住,消耗所有空闲CPU(按顶部显示100%CPU)。如果我在进程上使用来自CLI的strace,它会显示无尽的waitpid()系统调用序列。根据命令“ps”,此时没有子进程。

在这个问题之后我的服务器实现变得无法使用,只有它的重启有助于:(客户端可以连接但没有anwser,我想只是在操作系统端使用“backlog”队列,但是python代码从不接受连接。

它可以很容易地重现,例如使用一些私有的HTTP实现,以及一个浏览器(我使用chrome)和CTRL-R(重新加载)按住10秒钟。当然,问题是在没有这种“野蛮”尝试的情况下触发的,并且“在正常使用情况下”更为罕见,并且甚至很难知道可能是什么问题。我用os.fork()和socket函数编写了自己的SocketServer实现,并没有出现这个问题,但我对一些“已经准备好”和“标准”的解决方案感到满意。

问题:这不是一件好事,因为实现服务器的脚本可以通过这种方式轻松实现DoS。

我能注意到:我为SIGCHLD安装了一个单一的处理程序。似乎如果我删除它,我无法重现问题,然而我可以看到僵尸进程(我猜他们不是等待()'ed)。即使我使用signal.SIG_IGN安装信号处理程序,我也会解决这个问题。

任何人都可以帮助解决问题以及如何解决这个问题?我还是喜欢使用单一的处理程序,因为离开很多僵尸进程也不是那么好,特别是在长时间运行之后。

感谢您的任何想法。

1 个答案:

答案 0 :(得分:0)

可能相关:What is the cost of many TIME_WAIT on the server side?

您可能在time_wait状态下拥有所有最大连接数。

  • 检查sysctl net.core.somaxconn是否有最大连接数。
  • 检查sysctl net.ipv4了解其他配置详情(例如tw
  • 检查ulimit -n是否有最大打开文件描述符(包括套接字)
  • 您可以尝试:sysctl net.ipv4.tcp_tw_reuse=1快速重用这些套接字(除非您知道自己在做什么,否则不要启用它。)
  • 检查文件句柄泄漏。

[不那么]愚蠢的问题:你的SocketServer实现与标准的+ ForkingMixIn有什么不同?

然而,滥用ForkingMixIn(叉炸弹)真的很容易,你可能想要使用绿色线程,例如eventlet库(http://eventlet.net/doc/index.html

这可能是你的问题。