在 Django 下执行 long-运行 tasks/batches 的可靠方法是什么?

what is a robust way to execute long-running tasks/batches under Django?

我有一个 Django 应用程序,旨在 运行 在 LAN 上的 Virtualbox 虚拟机上。基本用户将是精明的 IT 最终用户,而不是系统管理员。

该应用程序的部分工作是连接到 LAN 上的外部数据库,运行 一些 python 批处理这些数据库并将结果保存在其本地数据库中。然后用户可以使用 Django 页面浏览系统。

运行 批次的时间不是那么长,但 运行 秒到几分钟,可能是几十分钟,而不是几秒钟。 运行频率充其量是不频繁的,我想你可以花几天时间而不需要刷新。

这不是 celery 的长任务的正常用例,它最终会通过 ajax and/or 轮询将结果推回网络 UI。它更类似于开发人员偶尔使用 django-admin 命令,但这次是针对最终用户的。

用户应该能够在需要时启动一个或多个批次的 运行 以刷新给定外部数据库的计算(目标数据库是批次的参数) .

在为给定数据库完成批处理之前,该应用程序确实无法使用。您可以访问其页面,但许多功能将无法使用。

这非常重要,从支持的角度来看,批处理始终很容易 运行可用。下降到虚拟机 SSH 可能需要频繁的手持操作,这不太好——最好从 Django 网页启动它们。

我目前拥有的:

每批都有自己的脚本。

  1. 我可以在命令行上 运行(通过 if __name__ == "main":)。

  2. 这些批次也被连接为 celery 任务,并且可以正常工作。

  3. 鉴于我编写它们的方式,允许从 Python 中的子进程调用中 运行ning 它们相对容易。我还没有真正研究过它,但我想我也可以将它们变成 django-admin 命令。

  4. 这些批次已经有了自己的基本状态检查。例如,他们可以查看计算的数据并判断它们是否已经 运行 并将其显示在 Django 页面中,而无需查看 celery 任务状态后端。

  5. 批次本身相对健壮,我可以使它们更健壮。这是关于他们的启动机制。

有什么不太好。

在 Mac 开发环境中,我发现 celery/celerycam/rabbitmq 堆栈有些不稳定。似乎有时 rabbitmqs 守护进程在 CPU/RAM 使用中膨胀,然后需要终止。这极大地混淆了芹菜进程,我发现我必须 kill -9 各种任务并手动重新启动它们。有时 celery 仍然有效,但 celerycam 不工作,因此没有任务更新。其中一些问题可能是 OSX 特定的,或者可能是由于现在切换了 DEBUG 标志,celery 会发出警告。

然后我需要 运行 命令行上的批处理,这是我试图避免的,直到整个 celery 堆栈被重置。

这在普通网站上可能是可以接受的,有管理员监督。但是我不能在只有用户有权访问的远程虚拟机上发生这种情况。

考虑到这些批次有些是一劳永逸的,我想知道此时芹菜是否还不过分。

我考虑过的一些方案:

  1. 编写清理 shell/Python 脚本以重新启动 rabbitmq/celery/celerycam 并通常使其更健壮。即使芹菜和所有东西更稳定所需的一切。我已经使用 psutil 来确定 rabbit/celery 进程正在 运行ning 并在 Django 中显示它们的状态。

  2. 运行改为通过 subprocess 批处理,避免使用芹菜。这里的 django-admin 命令怎么样?这有什么区别吗?还是需要从网页上运行

  3. 替代task/process celery 的管理器功能较少但活动部件较少?

  4. 不使用 subprocess 而是依赖 Python multiprocessing 模块?老实说,我不知道这与通过子流程启动相比如何。

环境: nginx、wsgi、ubuntu 在 vi​​rtualbox 上,负责构建虚拟机。

我不确定你的 celery 配置是如何让它变得不稳定的,但听起来它仍然是解决你问题的最佳选择。我使用 redis 作为队列系统,根据我自己的经验,它比 rabbitmq 工作得更好。也许你可以试试看它是否改善了一些事情。

否则,只需使用 cron 作为 运行 周期性任务的驱动程序。你可以让它 运行 你的脚本定期更新数据库,你的 UI 组件将在没有冲突的情况下轮询数据库。