web-dev-qa-db-ja.com

Dockerコンテナとして実行されているCelery&RabbitMQ:タイプ「...」の未登録タスクを受信しました

私はdocker、celery、rabbitMQに比較的慣れていません。

私たちのプロジェクトでは、現在、次のセットアップがあります。複数のDockerコンテナーが実行されている1つの物理ホスト:

1xrabbitmq:3-管理コンテナ

# 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

(さらにいくつかのコンテナーがありますが、問題に対して何もする必要はありません)

タスクファイル

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

全体のセットアップは実際にはかなりうまく機能しているようです。したがって、tasks.pyが配置されているディレクトリでpython Shellを開いて、実行すると

>>> 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'

したがって、問題は明らかに、セロリコンテナ内のセロリ労働者がタスクモジュールを知らないということのようです。私はDockerのスペシャリストではないので、タスクモジュールをセロリコンテナにインポートするのに最適な方法を尋ねたいと思いました。

どんな助けでも大歓迎です:)


2015年4月8日編集、21:05:

答えてくれたIsowenに感謝します。完全を期すために、私がしたことは次のとおりです。

私のtasks.py/home/platzhersh/celerystuffのローカルマシンにあると仮定しましょう。ここで、同じディレクトリに次の内容のceleryconfig.pyを作成しました。

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

Isowenが述べたように、セロリはコンテナの/home/userでタスクと設定ファイルを検索します。したがって、開始時に/home/platzhersh/celerystuffをコンテナにマウントします。

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

これは私にとってトリックでした。これが同様の問題を抱えている他の人々に役立つことを願っています。タスクを別のDockerコンテナーにも配置することで、そのソリューションを拡張してみます。

17
platzhersh

ご想像のとおり、問題はセロリ労働者がタスクモジュールを知らないためです。あなたがする必要がある2つのことがあります:

  1. タスク定義をDockerコンテナに「入れて」ください。
  2. これらのタスク定義をロードするようにセロリワーカーを構成します。

アイテム(1)の場合、最も簡単な方法は、おそらく "Docker Volume" を使用して、コードのホストディレクトリをcelerydockerインスタンスにマウントすることです。何かのようなもの:

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として定義しているためです。

(注:項目(1)を実行する別の方法は、コード「組み込み」を使用してカスタムDockerイメージを作成することですが、これは読者の演習として残しておきます。)

項目(2)の場合、タスクファイルをインポートするセロリ構成ファイルを作成する必要があります。これはより一般的な問題なので、以前のスタックオーバーフローの回答を指摘します: Celery Received unregistered task of type(run example)

11
lsowen