我正在使用 mod_wsgi 通过 Apache 为 django 站点提供服务。我还有一些作为后台进程运行的 Python 代码(dameon?)。它不断轮询服务器并将数据插入其中一个 Django 模型。这工作正常,但我可以让这段代码成为我的 Django 应用程序的一部分,并且能够在后台持续运行吗?它本身不需要是一个过程,而是不断活跃的 Django 站点的艺术。如果是这样,您能否指出一个示例或一些可以帮助我完成此任务的文档?
谢谢。
我正在使用 mod_wsgi 通过 Apache 为 django 站点提供服务。我还有一些作为后台进程运行的 Python 代码(dameon?)。它不断轮询服务器并将数据插入其中一个 Django 模型。这工作正常,但我可以让这段代码成为我的 Django 应用程序的一部分,并且能够在后台持续运行吗?它本身不需要是一个过程,而是不断活跃的 Django 站点的艺术。如果是这样,您能否指出一个示例或一些可以帮助我完成此任务的文档?
谢谢。
您可以设置一个运行您定义的某些功能的 cron 作业,或者 - 更高级且可能推荐的方法,将celery集成到您的项目中(实际上这很容易)。
您可以在首次导入 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 作业中完成工作并执行它。命令行脚本意味着偶尔的临时内存使用,但作业的启动成本更高,因为每次都需要加载所有内容。
我之前使用了一个 cron 工作,但我告诉你,你会在一段时间后切换到 celery。
芹菜是要走的路。另外,您可以分配长异步过程,以便加快请求/响应时间。