2015-04-10 7 views
2

У меня есть приложение Django 1.62, работающее на Debian 7.8 с Nginx 1.2.1 в качестве моего прокси-сервера и Gunicorn 19.1.1 в качестве моего сервера приложений. Я установил Celery 3.1.7 и RabbitMQ 2.8.4 для обработки асинхронных задач. Я могу начать сельдерей работника как демон, но всякий раз, когда я пытаюсь запустить тест «добавить» задачу, как показано на сельдерей документы, я получаю следующее сообщение об ошибке:Почему демона сельдерея не видит задачи?

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». Задача «добавить» находится в приложениях/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 

Вот мои приложения сельдерея и конфигурационные файлы:

# 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://[email protected]:5672//' 
CELERY_RESULT_BACKEND = 'amqp' 
CELERY_ACCEPT_CONTENT = ['json', ] 
CELERY_TASK_SERIALIZER = 'json' 
CELERY_RESULT_SERIALIZER = 'json' 

Это мой сельдерея файл демон конфигурации. Я прокомментировал 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 

Я могу видеть из файла журнала, когда я запускаю команду «Суд сервис celeryd начать», сельдерей начинается без каких-либо ошибок. Однако, если я открываю оболочку Python и запускаю следующие команды, я увижу ошибку, которую я описал в начале.

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

Что интересно, если я исследую зарегистрированные задачи сельдерея в объекте, задача находится в списке:

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 и добавляет некоторые дополнительные зависящие от производства настройки.

Может ли кто-нибудь сказать мне, что я делаю неправильно? Я пробовал эту проблему уже три дня.

Спасибо!

+0

Использование этого: https://stackoverflow.com/a/10236402/3982673 –

ответ

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

+0

Мой файл tasks.py находится в apps.photos.tasks, поэтому я изменил декоратор для метода add на "@ app.task (name = 'apps.photos.tasks.add'), но я все равно получаю KeyError. – William

+0

, если вы начинаете свой рабочий с опцией '-l info', ваше имя задачи отображается в начале? – ChillarAnand

+0

Нет, я тоже это пробовал и заметил что никаких задач не показывалось. Я начал создавать тестовое приложение Django и сейчас читаю документы Celery на странице и пробую разные вещи, чтобы попытаться понять, где проблема в моей конфигурации. Прошло уже пять дней. самый длинный, который я когда-либо работал над проблемой, не найдя решения. – William

0

Я использую сельдерей 4.0.2 и Джанго, и я создал пользователя сельдерея и группу для использования с celeryd и была такая же проблема. Версия командной строки работала нормально, но celeryd не регистрировал задачи. Это не относительная проблема именования.

Решение заключалось в том, чтобы добавить пользователя сельдерея в группу, которая может получить доступ к проекту django. В моем случае эта группа является www-данными с чтением, исполнением и без записи.

Смежные вопросы