【问题标题】:How to decouple Django and Celery?如何解耦 Django 和 Celery?
【发布时间】:2016-09-09 07:37:19
【问题描述】:

在我的 celery 任务中,我有一个使用在 GPU 上运行的 python 模块(theano)的任务,该模块只能由一个线程同时导入。但要启动网站,我必须运行:

python manage.py runserver
celery -A celery_try worker -l info

所以模块会被 celery 和 django 网站都导入,这是冲突的。有没有办法解耦 Django 和 Celery,使模块只导入一次?

【问题讨论】:

  • 我不知道为什么运行这两个进程意味着你必须在两个进程中都导入模块。如果您不想将其导入其中之一,那就不要。
  • 在 Django 视图中,我导入了任务,因此 Django 服务器导入相同的模块 tasks.py 导入,而 celery 也导入任何 tasks.py 导入,这就是两个进程导入模块的方式。
  • celery 本身默认在 django 之外运行!这就是你初始化它的方式,例如如果您的模块正在加载所有 django 堆栈和所有 django 应用程序
  • 还有一件事 - 每个工作人员将在自己的子进程或线程中运行 - 所以如果你有 2 个工作人员,每个工作人员都会加载 theano 模块并且你会遇到同样的问题,也许编写你自己的最小服务器到处理任务,您将确保它运行一次,并且您可以完全控制它的运行方式

标签: python django celery django-celery


【解决方案1】:

出于测试目的,您可以在单线程模式下运行 django 开发服务器:python manage.py runserver --nothreading

您只想在 celery 工作进程中import theano,而不是在 django Web 服务器进程中,对吗?好的,让我们有条件地导入,以便它在 celery 中而不是在 django 中导入。

import os

try:
    # next line will raise exception in django, but will work fine in celery
    is_worker = os.environ['celery_worker']  
    import theano  # celery will import theano, django won't
except Exception as exc:
    # django code will catch exception that celery_worker doesn't exist and print it here
    print exc

然后使用 celery_worker 环境变量集启动您的 celery worker:

celery_worker=yes celery -A celery_try worker -l info

为了区分 celery worker 和 django,让我们在 celery 进程中设置一个 bash 环境变量,而不是在 django 进程中。我称该变量为celery_worker。为了设置它,我在celery -A celery_try worker -l info 前面加上per-command env variable assignmentcelery_worker=yes。现在,在 python 代码中,我检查环境变量是否存在。如果是,我们在 celery worker 中,需要导入 theano。

如果我们在 django 中,则不应定义 os.environ['celery_worker'] 并应引发异常。

【讨论】:

  • python manage.py runserver --nothreading 不起作用,我仍然收到相同的错误消息。而且我不太了解您的解耦解决方案,您能解释一下吗?谢谢。
  • @Demonedge 你想import theano 只在 celery 工作进程中,而不是在 django web 服务器进程中,对吧?好的,让我们有条件地导入,以便它在 celery 中而不是在 django 中导入。为了区分 celery worker 和 django,让我们在 celery 进程中设置一个 bash 环境变量,而不是在 django 进程中。我称该变量为celery_worker。为了设置它,我在celery -A celery_try worker -l info 前面加上了每个命令的环境变量赋值:celery_worker=yes。现在,在 python 代码中,我检查环境变量是否存在以及是否是 import theano。
  • 问题是我不能选择不导入Theano。当我启动服务器时,views.py 将自动从 Celery 导入任务,这将导入 Theano。当我运行 Celery work 处理任务时,Celery 将再次导入 tasks.py,这将再次导入 Theano。
  • 不,你可以!只需使导入有条件。我在示例中添加了一些代码内 cmets,使其更加明确。如果os.environ['celery_worker'] 不存在,则不会导入theano,如果存在-theano 将被导入。如果你运行python manage.py runserver,celery_worker 是未定义的并且 theano 不会被导入。如果您正在运行 celery,则定义了 celery_worker,因此会发生导入。
猜你喜欢
  • 2017-06-01
  • 2021-11-02
  • 2018-03-13
  • 1970-01-01
  • 2015-02-13
  • 2015-08-25
  • 2023-03-04
  • 2013-03-16
  • 2011-07-24
相关资源
最近更新 更多