【发布时间】:2018-09-09 08:58:30
【问题描述】:
我将非常感谢您的帮助!
这是我第一次尝试在 Docker 容器中使用 Celery 和 Django,经过数小时的阅读和试验,我无法解决这个问题。
问题
我可以从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 | -------------- 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 和 worker 之间的某种形式的通信。我还想知道我是否只是错误地启动了工人,或者根本没有。我真的说不出来。
我已经仔细检查了我的环境变量是否已在 django 和 worker 容器中设置。
设置
我在 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 和 worker 容器:
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
【问题讨论】:
-
我看到了 2 个问题。 1)
from .models import AddStore我建议使用from APPNAME.models import AddStore2)在def add(x, y):这一行之后将其导入add函数。 -
谢谢,但这似乎不是问题。即使我注释掉模型对象引用, .get() 也不会返回任何结果。它只是挂起。
-
所以您删除了
new = AddStore(value=value) and new.save()拖线并导入并尝试了? -
然后尝试使用共享任务,
@shared_task写下这一行而不是@app.task并且再尝试@app.task(bind=True)而不是@app.task -
我想通了...我清理了 celery worker 命令以设置
--loglevel=DEBUG,然后删除了 -Q 和 -n 选项,它工作得很好!
标签: django docker redis rabbitmq celery