【问题标题】:mod_wsgi won't allow a child process to exitmod_wsgi 不允许子进程退出
【发布时间】:2015-12-29 03:01:35
【问题描述】:

我使用 CherryPy、Apache 和 mod_wsgi 构建了一个网站,除了一个问题之外,一切都很好。当用户操作要求自动发送电子邮件时,我有时使用os.fork 以便父进程可以立即返回并给用户一个“OK”消息,而子进程负责发送电子邮件(可能需要几秒钟,我不希望用户必须等待)。

当子进程完成其工作并调用sys.exit() 时,就会出现问题。似乎 mod_wsgi 捕获了SystemExit 异常,将回溯转储到我的 Apache 错误日志中,并保持子进程运行。我有两个问题:

  1. 它使 Apache 错误日志杂乱无章,并带有不代表任何实际错误的回溯,并且

  2. 它让进程继续运行,浪费系统资源。更糟糕的是,这些休眠进程中有多少会随着时间累积?

作为记录,Apache 错误日志中的输出如下所示:

mod_wsgi (pid=14900): SystemExit exception raised by WSGI script '/Users/me/myscript.py' ignored.

随后是导致 sys.exit() 调用的回溯。

我猜this 解释了为什么 mod_wsgi 捕获了SystemExit 异常,但这对我没有帮助。

如果有一种方法可以配置 mod_wsgi 的行为,那就太好了,但是当我在 the docs 中搜索“SystemExit”和“sys.exit”时,都没有找到任何东西。

在这个站点上搜索“mod_wsgi SystemExit”只得到六篇文章,而且没有一篇是询问如何允许子进程退出。

有谁知道我怎样才能让子进程真正退出,并使 mod_wsgi 不会将任何内容转储到 Apache 错误日志中?

【问题讨论】:

    标签: python apache mod-wsgi cherrypy


    【解决方案1】:

    一般来说,您不应该在托管在您未创建的服务器进程中的代码中使用fork()。它通常会导致奇怪的流程生命周期问题,类似于您在此处描述的问题。 (这超越了 Apache、WSGI 或 Python;它适用于各种情况。)

    如果可以选择,我建议使用单独的工作队列来处理异步任务。对于 Python,一个常用的选项是Celery

    如果这绝对不是一个选项,您可以绕过SystemExit 异常并通过调用os._exit() 在Python 中立即退出。但是,请注意这可能仍会导致一些奇怪的行为,我不建议这样做。

    【讨论】:

    • 好的,谢谢。没有事先讨论确实让我怀疑我是否以一种根本错误的方式来处理这个问题。芹菜看起来不错,但我想知道它是否比我需要的火力更大。每次我想发送电子邮件时,您会发现仅使用 Python 的内置 threading 模块来启动新线程有什么问题吗?或者这是否会再次导致您提到的相同类型的流程生命周期问题?
    • @ssk 最好避免。这并不像 fork 一个子进程那么糟糕,但是创建一个比父请求更长的线程仍然很奇怪。
    猜你喜欢
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2010-09-21
    相关资源
    最近更新 更多