Подтвердить что ты не робот

Celery & RabbitMQ работает как контейнеры докеров: Получена незарегистрированная задача типа "..."

Я относительно новичок в докерах, сельдереях и кроликах.

В нашем проекте мы в настоящее время имеем следующую настройку: 1 физический узел с несколькими контейнерами докеров:

1x rabbitmq: контейнер с тремя контейнерами

# pull image from docker hub and install
docker pull rabbitmq:3-management
# run docker image
docker run -d -e RABBITMQ_NODENAME=my-rabbit --name some-rabbit -p 8080:15672 -p 5672:5672 rabbitmq:3-management

1x контейнер для сельдерея

# pull docker image from docker hub
docker pull celery
# run celery container
docker run --link some-rabbit:rabbit --name some-celery -d celery

(есть еще несколько контейнеров, но им не нужно ничего делать с проблемой)

Файл задачи

Чтобы узнать немного сельдерея и rabbitmq, я создал файл tasks.py на физическом хосте:

from celery import Celery

app = Celery('tasks', backend='amqp', broker='amqp://guest:[email protected]/')

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

Вся настройка, похоже, работает на самом деле неплохо. Поэтому, когда я открываю оболочку python в каталоге, где находится task.py и запускается

>>> from tasks import add
>>> add.delay(4,4)

Задача ставится в очередь и напрямую вытягивается у работника сельдерея.

Однако работник сельдерея не знает модуль задач относительно журналов:

$ docker logs some-celery


[2015-04-08 11:25:24,669: ERROR/MainProcess] Received unregistered task of type '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.

The full contents of the message body was:
{'callbacks': None, 'timelimit': (None, None), 'retries': 0, 'id': '2b5dc209-3c41-4a8d-8efe-ed450d537e56', 'args': (4, 4), 'eta': None, 'utc': True, 'taskset': None, 'task': 'tasks.add', 'errbacks': None, 'kwargs': {}, 'chord': None, 'expires': None} (256b)
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/site-packages/celery/worker/consumer.py", line 455, in on_task_received
strategies[name](message, body,
KeyError: 'tasks.add'

Таким образом, очевидно, что проблема заключается в том, что работники сельдерея в контейнере сельдерея не знают модуль задач. Теперь, поскольку я не специалист по докерам, я хотел спросить, как лучше всего импортировать модуль задач в контейнер для сельдерея?

Любая помощь приветствуется:)


РЕДАКТИРОВАТЬ 4/8/2015, 21:05:

Спасибо Исоуну за ответ. Только для полноты вот что я сделал:

Предположим, что мой tasks.py находится на моей локальной машине в /home/platzhersh/celerystuff. Теперь я создал celeryconfig.py в том же каталоге со следующим содержимым:

CELERY_IMPORTS = ('tasks')
CELERY_IGNORE_RESULT = False
CELERY_RESULT_BACKEND = 'amqp'

Как упоминал Исовен, сельдерей ищет /home/user контейнера для задач и файлов конфигурации. Поэтому мы монтируем /home/platzhersh/celerystuff в контейнер при запуске:

run -v /home/platzhersh/celerystuff:/home/user --link some-rabbit:rabbit --name some-celery -d celery

Это помогло мне. Надеюсь, это поможет некоторым другим людям с подобными проблемами. Теперь я попытаюсь расширить это решение, поставив задачи в отдельный контейнер докеров.

4b9b3361

Ответ 1

Как вы подозреваете, проблема в том, что работник сельдерея не знает модуль задач. Вам нужно сделать две вещи:

  • Определите определения задач в контейнере докеров.
  • Настройте рабочего сельдерея для загрузки этих определений задач.

Для элемента (1) наиболее простым способом является использование "Docker Volume" для монтирования главного каталога вашего кода на экземпляр докелета сельдерея. Что-то вроде:

docker run --link some-rabbit:rabbit -v /path/to/host/code:/home/user --name some-celery -d celery 

Где /path/to/host/code - это ваш путь к хосту, а /home/user - путь к его монтированию в экземпляре. Почему /home/user в этом случае? Поскольку Dockerfile для изображения сельдерея определяет рабочий каталог (WORKDIR) как /home/user.

(Примечание. Еще один способ выполнения Item (1) - создать пользовательский образ докеры с кодом "встроенный", но я оставлю это как упражнение для читателя.)

Для элемента (2) вам необходимо создать файл конфигурации сельдерея, который импортирует файл задач. Это более общая проблема, поэтому я укажу на предыдущий ответ stackoverflow: Celery Получил незарегистрированную задачу типа (пример запуска)