我有一个自定义的 Django 应用,大约每 5,000 个请求就会变得无响应。在 apache 日志中,我看到以下内容:
Apr 13 11:45:07 www3 apache2[27590]: **successful view render here**
...
Apr 13 11:47:11 www3 apache2[24032]: [error] server is within MinSpareThreads of MaxClients, consider raising the MaxClients setting
Apr 13 11:47:43 www3 apache2[24032]: [error] server reached MaxClients setting, consider raising the MaxClients setting
...
Apr 13 11:50:34 www3 apache2[27617]: [error] [client 10.177.0.204] Script timed out before returning headers: django.wsgi
(repeated 100 times, exactly)
我相信我正在运行 WSGI 2.6 (/usr/lib/apache2/modules/mod_wsgi.so-2.6) 并具有以下配置:
Apache 配置
WSGIDaemonProcess site-1 user=django group=django threads=50
WSGIProcessGroup site-1
WSGIScriptAlias / /somepath/django.wsgi
/somepath/django.wsgi
import os, sys
sys.path.append('/home/django')
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
当这种情况发生时,我可以终止 wsgi 进程,服务器就会恢复。
>ps aux|grep django # process is running as user "django"
django 27590 5.3 17.4 908024 178760 ? Sl Apr12 76:09 /usr/sbin/apache2 -k start
>kill -9 27590
这让我相信问题在于已知问题:
死锁超时=sss (2.0+)
定义在检测到 Python GIL 上的潜在死锁后,在守护进程关闭并重新启动之前允许经过的最大秒数。默认值为 300 秒。此选项的存在是为了解决由于 rouge Python C 扩展模块在进入阻塞或长时间运行的操作时无法正确释放 Python GIL 而导致守护进程冻结的问题。
但是,我不确定为什么这种情况没有自动清除。我确实看到脚本超时恰好发生在最后一次成功页面渲染后 5 分钟,因此触发了死锁超时。但它实际上并没有终止该进程。
编辑:更多信息
- Apache 版本 2.2,使用工人 MPM
- wsgi 版本 2.8
- SELinux 未安装 l
- 不经常使用的 xml 包
- Ubuntu 10.04
答案1
您可以尝试添加请求数限制,在此限制之后守护进程将被回收(在外部进程执行此操作之前)。这可以通过添加 参数来maximum-requests
实现WSGIDaemonProcess
。
看https://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Defining_Process_Groups
或者,您可以调查“django”用户可以拥有多少进程。您可以通过以该用户身份打开 shellsu - django -s /bin/bash
并检查 的输出来检查这一点ulimit -a
。