带有wsgi的Django偶尔会因“脚本标题过早结束”而失败:

时间:2011-11-14 18:03:06

标签: python django mod-wsgi

我现在有一个网站在Apache2上运行了几个月,并且会定期打扰以下内容:

[Sat Nov 12 06:18:34 2011] [error] [client X.Y.Z.158] Premature end of script headers: sleepsoundly_wsgi.py
[Sat Nov 12 06:18:49 2011] [error] [client X.Y.Z.158] Premature end of script headers: sleepsoundly_wsgi.py

它已经运行了1000次请求没有问题,但是它会定期执行此操作几次,然后一切都会好的。上传大约300个文件(每个.5 MB)时会发生这种情况。每个文件分别上传,一次3个文件,225个文件上传正常,226和227失败,然后228 - >结束一切正常。它不是每次都这样做,偶尔也不会这些文件失败。另一个时间文件#291失败了,其余的都工作了。

除了这个神秘的消息外,我在日志中什么都没有。

我已经检查过,机器上唯一的python版本是2.7.1。我没有收到来自django的电子邮件,我没有得到任何关于可能发生的事情的正常线索。我很好奇如何开始排除故障。它自行恢复,上传文件的自动程序不断移动。我如何弄清楚在这种情况下发生了什么?

Server version: Apache/2.2.17 (Ubuntu)
Server built:   Sep  1 2011 09:25:26
mod_wsgi: Version: 3.3-2ubuntu2

Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)

wsgi.conf has no lines in it that are not commented out.

VirtualHost setup:
    WSGIDaemonProcess myemr user=mjones processes=1 maximum-requests=500 threads=15
    WSGIProcessGroup  myemr
    WSGIScriptAlias   / /var/www/Python/myemr/myemr/deploy/myemr_wsgi.py

myemr_wsgi.py
    from os.path import abspath, dirname, join
    import sys

    # For packages that don't play well with mod_wsgi
    sys.stdout = sys.stderr

    sys.path.insert(0, abspath(join(dirname(__file__), "../..")))
    sys.path.insert(0, abspath(join(dirname(__file__), "../../myemr")))
    sys.path.insert(0, abspath(join(dirname(__file__), "../../myemr/apps")))
    sys.path.insert(0, abspath(join(dirname(__file__), "../../lib/python2.7/site-packages/")))

    # We have to add both of these because they are  installed with git?
    sys.path.insert(0, abspath(join(dirname(__file__), "../../src/pinax/")))

    from django.core.handlers.wsgi import WSGIHandler
    import pinax.env

    # setup the environment for Django and Pinax
    pinax.env.setup_environ(project_path='myemr')

    # set application for WSGI processing
    application = WSGIHandler()

1 个答案:

答案 0 :(得分:5)

问题很可能是因为您将'maximum-requests'设置为500.这将导致mod_wsgi守护程序进程定期重新启动。由于mod_wsgi守护程序进程在多线程配置中运行,如果有一个卡住请求,或者在重启完成后强制关闭超时之前没有完成的长时间运行请求,那么它将因进程重启而中止。然后,Apache子工作进程将看到请求终止,而不返回带有您看到的消息的标头。

故事的道德,不要在生产系统中使用“最大请求”选项,除非你有一个非常好的理由,例如失控内存增长。

mod_wsgi的4.0版将有一个可选但略微更优雅的重启选项,可以应用于这种情况,但它仍然不能永远等待,并且卡住的请求仍然必须在某个时候中止,你仍然会看到消息。

顺便说一句,不指定'processes = 1',因为它默认为一个进程,任何使用'processes'选项,即使值为'1',也会导致'wsgi.multiprocess'设置为True。使用'processes = 1'只应在具有单个进程的情况下进行,并且您有许多Apache实例,您可以使用单个进程进行负载平衡。