1

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

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

在这个问题之后,我的服务器实现无法使用,只有重新启动有帮助:(客户端可以连接但没有 anwser,我猜操作系统端只使用了“积压”队列,但 python 代码从不接受连接。

它可以很容易地被复制,例如使用一些原始的 HTTP 实现,并且带有 CTRL-R(重新加载)的浏览器(我使用 chrome)按住大约 10 秒。当然,如果没有这种“残酷”的尝试,也很少会在“正常使用”的情况下触发问题,甚至很难想到可能是什么问题。我用 os.fork() 和套接字函数编写了自己的 SocketServer 实现,它没有这个问题,但我对一些“已经准备好”和“标准”的解决方案更满意。

问题:这不是一件好事,因为我实现服务器的脚本可以通过这种方式很容易地被 DoS 攻击。

我能注意到:我为 SIGCHLD 安装了一个信号处理程序。似乎如果我删除它,我就无法重现问题,但是我可以看到僵尸进程(我猜是因为它们没有等待())。即使我使用 signal.SIG_IGN 安装信号处理程序,我也会遇到这个问题。

任何人都可以帮助解决问题以及我如何解决这个问题?无论如何我都想使用信号处理程序,因为留下许多僵尸进程也不是很好,尤其是在长时间运行之后。

感谢您的任何想法。

4

1 回答 1

0

也许相关:服务器端许多 TIME_WAIT 的成本是多少?

您的所有最大连接数可能都处于 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

这可能是你的问题。

于 2012-10-11T07:33:53.123 回答