为什么Celery守护进程看不到任务?

时间:2015-04-10 12:37:52

标签: python django debian celery

我在Debian 7.8上运行了一个Django 1.62应用程序,其中Nginx 1.2.1作为我的代理服务器,Gunicorn 19.1.1作为我的应用程序服务器。我已经安装了Celery 3.1.7和RabbitMQ 2.8.4来处理异步任务。我能够将Celery工作者作为一个守护进程启动,但每当我尝试运行测试时,我都可以添加"如Celery文档中所示的任务,我收到以下错误:

Received unregistred task of type u'apps.photos.tasks.add'.
The message has been ignored and discarded.

Traceback (most recent call last):
File "/home/swing/venv/swing/local/lib/python2.7/site-packages/celery/worker/consumer.py", line 455, in on_task_received
strategies[name](message, body,
KeyError: u'apps.photos.tasks.add'

我的所有配置文件都保存在" conf"位于我的" myproj"正下方的目录项目目录。 "添加"任务在apps / photos / tasks.py中。

myproj
│
├── apps
    ├── photos
    │   ├── __init__.py
    │   ├── tasks.py
    conf
    ├── celeryconfig.py
    ├── celeryconfig.pyc
    ├── celery.py
    ├── __init__.py
    ├── middleware.py
    ├── settings
    │   ├── base.py
    │   ├── dev.py
    │   ├── __init__.py
    │   ├── prod.py
    ├── urls.py
    ├── wsgi.py

这是任务文件:

# apps/photos/tasks.py
from __future__ import absolute_import
from conf.celery import app

@app.task
def add(x, y):
    return x + y

以下是我的Celery应用程序和配置文件:

# conf/celery.py
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
from conf import celeryconfig

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'conf.settings')
app = Celery('conf')
app.config_from_object(celeryconfig)
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

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

# conf/celeryconfig.py
BROKER_URL = 'amqp://guest@localhost:5672//'
CELERY_RESULT_BACKEND = 'amqp'
CELERY_ACCEPT_CONTENT = ['json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

这是我的Celery守护程序配置文件。我评论了CELERY_APP,因为我发现如果我取消注释,Celery守护进程甚至不会启动。我还发现我需要添加" - config" CELERYD_OPTS的参数,以便守护进程启动。我创造了一个非特权的芹菜"可以写入日志和pid文件的用户。

# /etc/default/celeryd
CELERYD_NODES="worker1"
CELERYD_LOG_LEVEL="DEBUG"
CELERY_BIN="/home/myproj/venv/myproj/bin/celery"
#CELERY_APP="conf"
CELERYD_CHDIR="/www/myproj/"
CELERYD_OPTS="--time-limit=300 --concurrency=8 --config=celeryconfig"
CELERYD_LOG_FILE="/var/log/celery/%N.log"
CELERYD_PID_FILE="/var/run/celery/%N.pid"
CELERYD_USER="celery"
CELERYD_GROUP="celery"
CELERY_CREATE_DIRS=1

我可以从日志文件中看到,当我运行命令时," sudo service celeryd start",Celery启动没有任何错误。但是,如果我打开Python shell并运行以下命令,我会看到我在开头描述的错误。

$ python shell
In [] from apps.photos.tasks import add
In [] result = add.delay(2, 2)

有趣的是,如果我查看Celery的已注册任务对象,则会列出任务:

In [] import celery
In [] celery.registry.tasks

Out [] {'celery.chain': ..., 'apps.photos.tasks.add': <@task: apps.photos.tasks.add of conf:0x16454d0> ...}

此处的其他类似问题已经讨论过具有PYTHONPATH环境变量并且我没有这样的变量。我从来没有理解如何设置PYTHONPATH,如果没有它,这个项目已经运行了一年多。

我还应该添加我的生产设置文件是conf / settings / prod.py。它从base.py导入我的所有基础(层级无关)设置,并添加一些额外的生产相关设置。

谁能告诉我自己做错了什么?我已经在这个问题上挣扎了三天了。

谢谢!

2 个答案:

答案 0 :(得分:2)

由于相对导入错误,它看起来正在发生。

>>> from project.myapp.tasks import mytask
>>> mytask.name
'project.myapp.tasks.mytask'

>>> from myapp.tasks import mytask
>>> mytask.name
'myapp.tasks.mytask'

如果您使用的是相对导入,则应明确设置名称。

@task(name='proj.tasks.add')
def add(x, y):
   return x + y

结帐:http://celery.readthedocs.org/en/latest/userguide/tasks.html#automatic-naming-and-relative-imports

答案 1 :(得分:0)

我使用芹菜4.0.2和django,我创建了芹菜用户和组用于芹菜,并遇到了同样的问题。命令行版本工作正常,但celeryd没有注册任务。这不是一个相对命名问题。

解决方案是将芹菜用户添加到可以访问django项目的组中。在我的例子中,这个组是带有读,执行和无写的www数据。