1

我有一个 Django Web 应用程序,我有一些应该在后台运行(或实际上:启动)的任务。

应用部署如下:

  • apache2-mpm-worker;
  • mod_wsgi 处于守护程序模式(1 个进程,15 个线程)。

后台任务具有以下特点:

  • 他们需要定期运行(每 5 分钟左右);
  • 它们需要应用程序上下文(即应用程序包需要在内存中可用);
  • 除了访问数据库之外,它们不需要任何输入,以执行一些不太繁重的任务,例如发送电子邮件和更新数据库的状态。

现在我在想,解决这个问题的最简单的方法就是简单地搭载现有的应用程序进程(由 mod_wsgi 产生)。通过将任务实现为应用程序的一部分并为其提供 HTTP 接口,我可以防止将所有应用程序保存到内存中的另一个进程的开销。可以设置一个简单的 cronjob,每 5 分钟向这个 HTTP 接口发送一个请求,就是这样。由于应用程序进程提供 15 个线程,而且任务非常轻量级,并且每 5 分钟运行一次,我认为它们不会妨碍 Web 应用程序面向用户的操作的性能。

然而......我做了一些在线研究,我没有看到没有人提倡这种方法。许多文章提出了一种基于成熟消息传递组件(例如Celery,它使用 RabbitMQ)的更复杂的方法。虽然这很性感,但对我来说听起来有点矫枉过正。一些文章建议设置一个 cronjob 来执行执行任务的脚本。但这也不是很吸引人,因为它会导致创建一个新进程,将整个应用程序加载到内存中,执行一些小任务,然后再次销毁该进程。每 5 分钟重复一次。听起来不像是一个优雅的解决方案。

因此,我正在寻找一些关于我在前一段之前的段落中描述的建议方法的反馈。我的推理正确吗?我是否忽略了(潜在的)问题?我假设应用程序的性能不会受到阻碍呢?

4

2 回答 2

1

根据您的具体要求,所有这些都是合理的方法。

另一种方法是在加载 WSGI 脚本时在进程中启动一个后台线程。该后台线程可以简单地休眠并偶尔唤醒以执行所需的工作,然后再进入休眠状态。

此方法需要您最多有一个后台线程运行的 Django 进程,以避免不同的处理在任何数据库等上执行相同的工作。

像您一样使用带有单个进程的守护程序模式将满足该标准。即使在多进程配置中,您也可能有其他方法可以实现这一目标。

于 2010-04-21T01:33:36.793 回答
0

请注意,芹菜在没有 RabbitMQ 的情况下也可以工作。它可以使用 ghetto 队列(SQLite、MySQL、Postgres 等,以及 Redis、MongoDB),这在测试或用于 RabbitMQ 似乎过大的简单设置中很有用。

请参阅http://ask.github.com/celery/tutorials/otherqueues.html (将 Celery 与 Redis/Database 一起用作消息队列。)

于 2010-04-22T13:54:43.227 回答