芹菜有效,但芹菜没有

时间:2014-11-08 07:29:52

标签: python django celery

我试图让Django和Celery在制作中发挥作用。我的Django项目的布局如下:

- project_root
  - manage.py
  - app1
    - settings.py
    - celery_config.py
    - __init__.py, models.py, etc...
  - app2
    - tasks.py
    - __init__.py, models.py, etc...
  - app3
    - tasks.py
    - __init__.py, models.py, etc...

依旧......

现在,在开发期间,我可以在project_root中运行celery -A app1 worker -l info。这可以自动检测其他应用程序中的任务,并且运行正常。

对于生产,我显然需要运行celery作为守护进程。我已按照the celery websiteceleryd说明操作。

当我运行任务时(来自python manage.py shell或来自正在运行的Django应用程序),我得到:

>>> from app2.tasks import add
>>> result = add.delay(1,1)
>>> result.ready()
False
>>> result.get(timeout=1)
TimeoutError
... traceback

add()只是一个用于测试目的的简单函数:

@shared_task
def add(x, y):
    return x + y

在芹菜日志中,我得到:

[2014-11-08 12:43:59,191: INFO/MainProcess] Connected to amqp://guest:**@127.0.0.1:5672//
[2014-11-08 12:43:59,196: INFO/MainProcess] mingle: searching for neighbors
[2014-11-08 12:44:00,205: INFO/MainProcess] mingle: all alone
[2014-11-08 12:44:00,228: WARNING/MainProcess] w1@ubuntu ready.
[2014-11-08 12:44:09,216: ERROR/MainProcess] Received unregistered task of type 'app2.tasks.add'.
The message has been ignored and discarded.

Did you remember to import the module containing this task?
Or maybe you are using relative imports?
Please see http://bit.ly/gLye1c for more information.

{'utc': True, 'chord': None, 'args': (1, 2), 'retries': 0, 'expires': None, 'task': 'app2.tasks.add', 'callbacks': None, 'errbacks': None, 'timelimit': (None, None), 'taskset': None, 'kwargs': {}, 'eta': None, 'id': '82e59cbf-88be-4542-82a7-452f2fbafe95'} (213b)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/worker/consumer.py", line 455, in on_task_received
    strategies[name](message, body,
KeyError: 'app2.tasks.add'

以下是我的/etc/default/celeryd供参考:

CELERYD_NODES="w1"
CELERYD_CHDIR="/var/django/project_root"
CELERYD_OPTS="--concurrency=1"
CELERY_CONFIG_MODULE="app1.celery_config"
CELERYD_LOG_FILE="/var/log/celery/%n.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_USER="celery"
CELERYD_GROUP="celery"
CELERY_RESULT_BACKEND="amqp"
CELERY_CREATE_DIRS=1

我的project_root/app1/celery_config.py

from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app1.settings')
app = Celery('app1', backend='amqp', broker='amqp://')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

@app.task(bind=True)
def debug_task(self):
        print('Request: {0!r}'.format(self.request))

如何让Celery作为守护进程正常工作?

2 个答案:

答案 0 :(得分:3)

你的芹菜实例/ app有命名问题。

解决方案:

celery -A app1 worker -l info
如果添加

正在运行

CELERY_APP_ARG="app1"

到你的celeryd文件,一切都应该正常。

注意:

使用芹菜很痛苦。它现在也被弃用了。所以你可以使用

<强> 1。芹菜多:

您可以在项目根目录中启动相同的工作程序,而不需要像这样的任何bash脚本

celery multi start my_awesome_worker -A app1 \
--pidfile="somewhere/celery/%n.pid" \
--logfile="somewhere/celery/%n.log"

此方法的另一个优点是,您可以在没有sudo权限的情况下启动守护程序。

<强> 2。监:

如果您已经在使用主管,那么您可以再为芹菜启动一个流程,这样可以轻松管理多个工作人员。

说明:

使用

从终端运行工作人员时
celery -A app1 worker -l info

在你的日志中,它会显示一个将要处理的任务列表,如下所示

[tasks]
  . app1.tasks.add

现在,如果你这样做

In [1]: from app1.tasks import add

In [2]: add.name
Out[2]: 'app1.tasks.name'      #attention please

In [3]: result = add.delay(1,1)

In [4]: result.ready()
Out[4]: True

In [5]: result.get(timeout=1)
Out[5]: 2

一切正常,因为注册的任务名称和您运行的任务名称是相同的。另一方面,如果你这样做

In [1]: from app1 import tasks

In [2]: tasks.add.name
Out[2]: 'tasks.name'     #attention please

In [3]: result = add.delay(1,1)

In [4]: result.ready()
Out[4]: False

In [5]: result.get(timeout=1)
Out[5]: TimeoutError                              Traceback (most recent call last)
        <ipython-input-10-ade09ca12a13> in <module>()
        ----> 1 r.get(timeout=1)

它会抛出错误,因为已注册的任务名称为app1.tasks.add,您排队的任务为tasks.add。所以你的工作人员不知道你添加的任务。有关此here的更多信息。

<强> Warining:

此外,如果您正在为另一个应用运行芹菜,请说foo

celery worker -l info -A foo

已注册任务bar

[tasks]
  . foo.tasks.bar

现在,如果您对旧app1.tasks.add进行排队,此工作人员将抛出关键错误。所以你必须导入&amp;正确地路由任务。

File "/usr/local/lib/python2.7/dist-packages/celery/worker/consumer.py", line 455, in on_task_received
KeyError: 'app1.tasks.add'

因为它不知道您排队的任务。你必须导入&amp; route tasks正确无误。

答案 1 :(得分:0)

解决方案原来是添加

CELERY_APP="app1"
CELERY_NODES="app1"

/etc/default/celeryd