我目前正在构建一个小型 django 项目,我决定使用 cookiecutter-django 作为基础,因为我需要的一切都包括在内。在设置项目时,我要求 cookiecutter-django 包含 Celery 的设置,我可以在项目中找到所有内容,到目前为止一切都很好。但是,我在让 Celery 正常运行方面确实存在一些问题。当我从应用程序启动任务时,什么也没有发生。
docker 容器都已正常启动。Django 和 Postgres 工作,Redis 启动了,我可以 bash 进入容器并查询它。从控制台输出中,我看到 celeryworker 容器已启动并正在运行。我还看到 Celery 正在识别我的任务:
celeryworker_1 | [tasks]
celeryworker_1 | . metagrabber.taskapp.celery.debug_task
celeryworker_1 | . scan_and_extract_meta
celeryworker_1 | . start_job
在对此感到困惑之后,我决定为 Flower 创建一个新的 Docker 容器,以查看引擎盖下发生了什么。有趣的是,我可以看到有一个工人并且它的名字是正确的(我比较了 Celery 容器中的工人 ID)。但是,如果我从我的一个观点开始一项任务,如下所示:
celery_task_id = start_job_task.delay(job.id)
我没有看到 Flower 上有任何任务。我可以看到它celery_task_id
获得了一个 UUID,但仅此而已。Flower 上什么都看不到(活动、已处理、失败、成功、重试的所有计数都保持为 0)。如果我在我的 Redis 容器中执行 bash 并使用,redis-cli
我看不到名为 的队列celery
,这仅意味着没有 Celery 任务。可能(我说可能)Flower在日志上留下了一条线索:
flower_1 | [W 180304 10:31:05 control:44] 'stats' inspect method failed
flower_1 | [W 180304 10:31:05 control:44] 'active_queues' inspect method failed
flower_1 | [W 180304 10:31:05 control:44] 'registered' inspect method failed
flower_1 | [W 180304 10:31:05 control:44] 'scheduled' inspect method failed
但老实说,我不知道这对我有什么帮助。
因此,我继续添加了一些日志记录以查看发生了什么,我发现实际上我的 Django 容器在我执行时尝试完成工作,start_job_task.delay(job.id)
而不是移交给 Celery。不知何故,我有一种感觉,这一切都与 Redis 有一些不好的联系。但是怎么做?docker-compose 文件中的配置看起来就像 cookiecutter 设置的方式一样:
redis:
image: redis:3.0
celeryworker:
<<: *django
depends_on:
- redis
- postgres
environment:
- C_FORCE_ROOT=true # just for local testing
ports: []
command: /start-celeryworker.sh
我还尝试手动公开 Redis 容器上的端口,但这并没有让我更进一步。
为了完整起见,这里是我的配置文件中的 Celery 设置。用 cookiecutter 设置:
# base.py
INSTALLED_APPS += ['mailspidy.taskapp.celery.CeleryConfig']
CELERY_BROKER_URL = env('CELERY_BROKER_URL', default='django://')
if CELERY_BROKER_URL == 'django://':
CELERY_RESULT_BACKEND = 'redis://'
else:
CELERY_RESULT_BACKEND = CELERY_BROKER_URL
# local.py
CELERY_ALWAYS_EAGER = True
任何想法为什么任务不被发送到芹菜?