芹菜任务.get()无效

时间:2018-03-30 10:03:32

标签: django docker redis rabbitmq celery

我真的很感激这方面的帮助!

这是我第一次尝试在Docker容器中使用带有Django的Celery,经过数小时的阅读和实验后,我无法通过这个问题。

问题

我可以从polls.task导入任务并使用.delay()运行,如下所示:

python manage.py shell
from polls.tasks import add
task = add.delay(4,4)

当我运行它时,我可以通过rabbitmq容器看到一条消息。

如果我执行task.id,我可以获得任务ID。

但是,如果我运行task.get()程序就会挂起。我看不到任何容器上的任何动作,我没有得到任何结果。

我还注意到,当我运行dc-up并启动所有容器时,我在worker容器上得到以下输出,这看起来是正确的,包括能够看到我的任务已注册:

worker      |  -------------- default@5d0902ad9e2a v4.1.0 (latentcall)
worker      | ---- **** ----- 
worker      | --- * ***  * -- Linux-4.9.87-linuxkit-aufs-x86_64-with-debian-8.10 2018-03-30 09:45:01
worker      | -- * - **** --- 
worker      | - ** ---------- [config]
worker      | - ** ---------- .> app:         composeexample:0x7f2f3255e320
worker      | - ** ---------- .> transport:   amqp://admin:**@rabbitmq:5672//
worker      | - ** ---------- .> results:     redis://redis:6379/0
worker      | - *** --- * --- .> concurrency: 2 (prefork)
worker      | -- ******* ---- .> task events: ON
worker      | --- ***** ----- 
worker      |  -------------- [queues]
worker      |                 .> default          exchange=default(direct) key=default
worker      | 
worker      | [tasks]
worker      |   . polls.tasks.add
worker      | [2018-03-30 10:45:34,722: INFO/MainProcess] Connected to amqp://admin:**@rabbitmq:5672//
worker      | [2018-03-30 10:45:34,746: INFO/MainProcess] mingle: searching for neighbors
worker      | [2018-03-30 10:45:35,799: INFO/MainProcess] mingle: all alone
worker      | [2018-03-30 10:45:35,827: INFO/MainProcess] default@a7d75a442646 ready.

我怀疑我错过了rabbitmq和工人之间的某种形式的沟通。我也想知道我是不是只是错误地启动了工人,或者根本就没有。我无法说出来。

我已经仔细检查过我的环境变量是在django和worker容器中设置的。

SETUP

我在Docker中有以下设置:Django,Redis(用于后端),RabbitMQ(用于消息),PSQL,Celery(用于工作者的单独容器)

这是我的Dockerfile:

FROM python:3
ENV PYTHONUNBUFFERED 1

ADD requirements.txt /code/

WORKDIR /code/

RUN apt-get update && apt-get install -y \
    sudo \
    git

RUN pip install --upgrade pip && pip install -r requirements.txt

# create unprivileged user
RUN adduser --disabled-password --gecos '' myuser

这是我的docker-compose.yml:

version: '3'

services:
  dbtest:
    image: postgres:10.1
    container_name: postgrestest
    expose:
      - "5432"
    volumes:
      - postgres_data:/var/lib/postgresl/data/
    networks:
      - lofi
  redis:
    image: redis:4.0.8
    container_name: redis
    networks:
      - lofi
  rabbitmq:
    image: rabbitmq:3.7.4
    container_name: rabbitmq
    env_file: .env
    ports:
      - "5672:5672"  # we forward this port because it's useful for debugging
      - "15672:15672"  # here, we can access rabbitmq management plugin
    networks:
      - lofi
  django:
    container_name: djcelerytest
    env_file: .env
    build:
      context: .
      dockerfile: Dockerfile
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
      - "8888:8888"
    depends_on:
      - dbtest
      - rabbitmq
    networks:
      - lofi
  worker:
    env_file: .env
    build:
      context: .
      dockerfile: Dockerfile
    container_name: worker
    command: sh ./run_celery.sh
    volumes:
      - .:/code
    depends_on:
      - rabbitmq
      - redis
    networks:
      - lofi

networks:
  lofi:

volumes:
  postgres_data:
    external: true

我在.env文件中有以下设置,用于设置Django和工作容器:

CELERY_BROKER_URL=amqp://admin:mypass@rabbitmq//
CELERY_RESULT_BACKEND=redis://redis:6379/0
RABBITMQ_DEFAULT_USER=admin
RABBITMQ_DEFAULT_PASS=mypass

这是run_celery.sh文件:

#!/bin/sh

# wait for RabbitMQ server to start
sleep 10

# run Celery worker for our project myproject with Celery configuration stored in Celeryconf
su -m myuser -c "celery worker -E -A composeexample.celeryconf -Q default -n default@%h  --loglevel=INFO"

我正在尝试运行的任务是tasks.py:

from composeexample.celeryconf import app
from .models import AddStore

@app.task
def add(x, y):
    value = x + y
    new = AddStore(value=value)
    new.save()
    return value

1 个答案:

答案 0 :(得分:0)

事实证明,在run_celery.sh文件中,启动芹菜工作者的命令包括-Q default选项,根据docs,该选项不再存在。

所以,如果你只是改变这个:

su -m myuser -c "celery worker -E -A composeexample.celeryconf -Q default -n default@%h  --loglevel=INFO"

到此:

su -m myuser -c "celery worker -E -A composeexample.celeryconf -n default@%h  --loglevel=INFO"

我可以毫无问题地致电task.get()