我可以让一些代码像守护进程一样在 Django 中不断运行吗
我正在使用 mod_wsgi 通过 Apache 为 django 站点提供服务。我还有一些作为后台进程运行的 Python 代码(dameon?)。它不断轮询服务器并将数据插入到 Django 模型之一。这工作正常,但是我可以让这段代码成为我的 Django 应用程序的一部分,并且能够在后台持续运行吗?它本身不需要是一个过程,而是持续活跃的 Django 站点的艺术。如果是这样,您能给我提供一个示例或一些文档来帮助我完成此任务吗?
谢谢。
I'm using mod_wsgi to serve a django site through Apache. I also have some Python code that runs as a background process (dameon?). It keeps polling a server and inserts data into one of the Django models. This works fine but can I have this code be a part of my Django application and yet able to constantly run in the background? It doesn't need to be a process per se but a art of the Django site that is active constantly. If so, could you point me to an example or some documentation that would help me accomplish this?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以设置一个 cron 作业来运行您定义的某些功能,或者 - 更高级且可能推荐的方法,集成 celery 在你的项目中(实际上这很简单)。
You could either set up a cron job that runs some function you have defined, or - the more advanced and probably recommended method, integrate celery in your project (which is quite easy, actually).
您可以在首次导入 WSGI 脚本时创建一个后台线程。
为此,您必须仅使用一个守护进程,否则每个进程都会执行您可能不希望的相同操作。
如果您在守护进程进程组中使用多个进程,另一种方法是创建一个特殊的守护进程进程组,其唯一目的是运行此后台线程。换句话说,该进程实际上并没有收到任何请求。
您可以通过以下方式做到这一点:
WSGIImportScript 指令表示加载该脚本并在启动时在进程组“django-jobs”的上下文中运行它。
为了避免使用多个脚本,我将其指向用于 WSGIScriptAlias 的原始 WSGI 脚本文件。不过,我们不希望它在由该指令加载时运行,所以我们这样做:
这里它查看守护进程进程组的名称,并且仅在使用单个进程设置的特殊守护进程进程组中启动时运行为了这。
总的来说,您只是将 Apache 用作一个伟大的进程管理器,尽管它已经被认为是强大的。这有点矫枉过正,因为这个过程除了接受和处理请求之外还会消耗额外的内存,但根据您正在执行的操作的复杂性,它仍然很有用。
这样做的一个可爱的方面是,由于它仍然是一个完整的 Django 应用程序,因此您可以将特定的 URL 映射到此进程,从而提供一个远程 API 来管理或监视后台任务及其正在执行的操作。
在这里,除了 /admin 下的内容之外的所有 URL 都在“django-site”中运行,而 /admin 在“django-jobs”中运行。
无论如何,这解决了根据要求在 Apache mod_wsgi 守护进程进程中执行此操作的具体问题。
正如所指出的,另一种方法是使用命令行脚本来设置和加载 Django,并完成工作并从 cron 作业执行该工作。命令行脚本意味着偶尔会使用短暂的内存,但作业的启动成本较高,因为每次都需要加载所有内容。
You could create a background thread from the WSGI script when it is first being imported.
For this to work though you would have to be using only one daemon process otherwise each process would be doing the same thing which you probably do not want.
If you are using multiple process in daemon process group, an alternative is to create a special daemon process group which the only purpose of is to run this background thread. In other words, the process doesn't actually receive any requests.
You can do this by having:
The WSGIImportScript directive says to load that script and run it on startup in the context of the process group 'django-jobs'.
To save having multiple scripts, I have pointed it at what would be your original WSGI script file you used for WSGIScriptAlias. We don't want it to run when it is loaded by that directive though, so we do:
Here it looks at the name of the daemon process group and only runs when started up within the special daemon process group set up with single process just for this.
Overall you are just using Apache as a big gloried process manager, albeit one which is already known to be robust. It is a bit of overkill as this process will consume additional memory on top of those accepting and handling requests, but depending on the complexity of what you are doing it can still be useful.
One cute aspect of doing this is that since it is still a full Django application in there, you could map specific URLs to just this process and so provide a remote API to manage or monitor the background task and what it is doing.
Here, all URLs except for stuff under /admin run in 'django-site', with /admin in 'django-jobs'.
Anyway, that addresses the specific question of doing it within the Apache mod_wsgi daemon process as requested.
As pointed out, the alternative is to have a command line script which sets up and loads Django and does the work and execute that from a cron job. A command line script means occasional transient memory usage, but startup cost for job is higher as need to load everything each time.
我以前使用过 cron 作业,但我告诉你,一段时间后你会切换到 celery。
芹菜是必经之路。另外,您可以分配较长的异步流程任务,以便加快请求/响应时间。
I previously used a cron job but I telling you, you will switch to celery after a while.
Celery is the way to go. Plus you can tasked long async process so you can speed up the request/response time.