我正在使用带有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安装信号处理程序,我也会解决这个问题。
任何人都可以帮助解决问题以及如何解决这个问题?我还是喜欢使用单一的处理程序,因为离开很多僵尸进程也不是那么好,特别是在长时间运行之后。
感谢您的任何想法。
答案 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)
这可能是你的问题。
这:http://twistedmatrix.com/trac/ticket/733
除非你在处理程序中采取一些额外的措施(SIGCHLD
,或在signal.siginterrupt(signal.SIGCHLD, False)
调用中使用唤醒fd),否则你会看到select()
处理程序不被禁止