我有一个在 Debian 7.8 上运行的 Django 1.62 应用程序,其中 Nginx 1.2.1 作为我的代理服务器,Gunicorn 19.1.1 作为我的应用程序服务器。我安装了 Celery 3.1.7 和 RabbitMQ 2.8.4 来处理异步任务。我可以将 Celery Worker 作为守护进程启动,但每当我尝试运行测试“添加”任务(如 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 才能启动守护进程。我创建了一个非特权的“celery”用户,可以写入日志和 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 导入我的所有基础(与层无关)设置,并添加一些额外的与生产相关的设置。
谁能告诉我我做错了什么?我已经为这个问题苦苦挣扎了三天了。
Thanks!