我正在使用mod_wsgi通过Apache为django站点提供服务。我还有一些作为后台进程运行的Python代码(dameon?)。它不断轮询服务器并将数据插入其中一个Django模型。这工作正常,但我可以将此代码作为我的Django应用程序的一部分,但能够在后台持续运行吗?它不需要是一个过程本身,而是一个不断活跃的Django网站的艺术。如果是这样,你能指点我的例子或一些文件来帮助我实现这个目标吗?
感谢。
答案 0 :(得分:14)
您可以设置运行某些已定义函数的cron作业,或者 - 更高级且可能推荐的方法,在项目中集成celery(实际上这非常简单)。
答案 1 :(得分:10)
您可以在首次导入时从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下的内容以外的所有网址都在'django-site'中运行,而/ admin在'django-jobs'中运行。
无论如何,它解决了在Apache mod_wsgi守护程序进程中按要求执行此操作的具体问题。
正如所指出的,另一种方法是使用命令行脚本来设置和加载Django并完成工作并从cron作业执行。命令行脚本意味着偶尔会出现瞬态内存使用情况,但是每次加载所有内容时,作业的启动成本都会更高。
答案 2 :(得分:0)
我之前使用过cron工作,但是我告诉你,过了一段时间你会转向芹菜。
芹菜是最佳选择。此外,您可以执行长异步过程,以便加快请求/响应时间。