【问题标题】:Django with wsgi sporadically fails with "Premature end of script headers:"带有 wsgi 的 Django 偶尔会因“脚本头过早结束:”而失败
【发布时间】:2011-11-14 18:03:06
【问题描述】:

我有一个在 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 个文件(每个 0.5 MB)时会发生这种情况。每个文件单独上传,一次3个文件,225个文件上传正常,226和227失败,然后228->end都正常。它不会每次都这样做,只是偶尔会这样做,而且这些文件并不总是失败。另一个时间文件 #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()

【问题讨论】:

  • 您确定您的主要 Apache 错误日志中没有“分段错误”消息吗?还要提供您正在使用的 WSGIDaemonProcess 配置,并说明您是否有任何机制来定期优雅地重新启动 Apache。
  • 添加了我的配置。想知道threaded: no 选项是否是问题所在......直到我开始尝试为这个问题记录这个问题时才意识到这一点。
  • 我检查了所有的日志并且“egmenation”没有出现在任何地方。

标签: python django mod-wsgi


【解决方案1】:

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

故事的寓意,不要在生产系统中使用“最大请求”选项,除非您有很好的理由,例如失控的内存增长。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 2011-11-01
    • 2012-06-25
    相关资源
    最近更新 更多