16

我正在使用 mod_wsgi 通过 Apache 为 django 站点提供服务。我还有一些作为后台进程运行的 Python 代码(dameon?)。它不断轮询服务器并将数据插入其中一个 Django 模型。这工作正常,但我可以让这段代码成为我的 Django 应用程序的一部分,并且能够在后台持续运行吗?它本身不需要是一个过程,而是不断活跃的 Django 站点的艺术。如果是这样,您能否指出一个示例或一些可以帮助我完成此任务的文档?

谢谢。

4

3 回答 3

14

您可以设置一个运行您定义的某些功能的 cron 作业,或者 - 更高级且可能推荐的方法,将celery集成到您的项目中(实际上这很容易)。

于 2011-06-30T09:38:24.797 回答
11

您可以在首次导入 WSGI 脚本时创建一个后台线程。

import threading
import time

def do_stuff():
    time.sleep(60)
    ... do periodic job

_thread = threading.Thread(target=do_stuff)
_thread.setDaemon(True)
_thread.start()

要使其工作,尽管您必须只使用一个守护进程,否则每个进程都将执行您可能不想要的相同操作。

如果您在守护进程组中使用多个进程,另一种方法是创建一个特殊的守护进程组,其唯一目的是运行此后台线程。换句话说,该进程实际上并没有收到任何请求。

您可以通过以下方式做到这一点:

WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
    process-group=django-jobs application-group=%{GLOBAL}

WSGIImportScript 指令表示加载该脚本并在启动时在进程组“django-jobs”的上下文中运行它。

为了避免使用多个脚本,我指出了您用于 WSGIScriptAlias 的原始 WSGI 脚本文件。我们不希望它在被该指令加载时运行,所以我们这样做:

import mod_wsgi

if mod_wsgi.process_group == 'django-jobs':
    _thread = threading.Thread(target=do_stuff)
    _thread.setDaemon(True)
    _thread.start()

在这里,它查看守护进程组的名称,并且仅在为此设置了单个进程的特殊守护进程组中启动时运行。

总的来说,您只是将 Apache 用作一个备受赞誉的进程管理器,尽管它已经众所周知是健壮的。这有点矫枉过正,因为这个过程会在接受和处理请求的基础上消耗额外的内存,但根据你正在做的事情的复杂性,它仍然很有用。

这样做的一个可爱的方面是,由于它仍然是一个完整的 Django 应用程序,您可以将特定的 URL 映射到这个进程,从而提供一个远程 API 来管理或监视后台任务及其正在做什么。

WSGIDaemonProcess django-jobs processes=1 threads=1
WSGIImportScript /usr/local/django/mysite/apache/django.wsgi \
    process-group=django-jobs application-group=%{GLOBAL}

WSGIDaemonProcess django-site processes=4 threads=5
WSGIScriptAlias / /usr/local/django/mysite/apache/django.wsgi

WSGIProcessGroup django-site
WSGIApplicationGroup %{GLOBAL}

<Location /admin>
WSGIProcessGroup django-jobs
</Location>

在这里,除了 /admin 下的所有 URL 都在 'django-site' 中运行,而 /admin 在 'django-jobs' 中。

无论如何,这解决了根据要求在 Apache mod_wsgi 守护进程中执行此操作的具体问题。

正如所指出的,替代方法是有一个命令行脚本来设置和加载 Django,并从 cron 作业中完成工作并执行它。命令行脚本意味着偶尔的临时内存使用,但作业的启动成本更高,因为每次都需要加载所有内容。

于 2011-06-30T10:05:01.227 回答
0

我之前使用了一个 cron 工作,但我告诉你,你会在一段时间后切换到 celery。

芹菜是要走的路。另外,您可以分配长异步过程,以便加快请求/响应时间。

于 2011-07-05T01:28:58.527 回答