【问题标题】:Not Getting Any Output from Dockerized Celery没有从 Dockerized Celery 获得任何输出
【发布时间】:2020-12-29 00:53:47
【问题描述】:

我一直在研究两个类似的教程(herehere),试图为我的 Django 项目创建计划任务,但我似乎无法从 Celery 服务中获得任何输出。

我已将 Celery 和 Redis 添加到 requirements.txt

Django==3.0.7
celery==4.4.7
redis==3.5.3

将 celery、celery-beat 和 redis 服务添加到docker-compose.yaml

version: "3.8"

services:
  cache:
    image: redis:alpine

  database:
    image: "postgis/postgis"
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: ${DATABASE_DEFAULT_USERNAME}
      POSTGRES_PASSWORD: ${DATABASE_DEFAULT_PASSWORD}

  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    depends_on:
      - cache
      - database
    env_file:
      - .env

  queue:
    build: .
    command: celery -A api worker -l info
    volumes:
      - .:/app
    links:
      - cache
    depends_on:
      - cache
      - database

  scheduler:
    build: .
    command: celery -A api beat -l info
    volumes:
      - .:/app
    links:
      - cache
    depends_on:
      - cache
      - database

celery.py 文件添加到api/api/ 目录。

import os

from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings')

app = Celery('api')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

将以下内容添加到api/api/__init__.py

from .celery import app as celery_app

__all__ = ('celery_app',)

api/server/tasks.py中创建了一个任务。

import logging

from celery import shared_task

logger = logging.getLogger(__name__)


@shared_task
def sample_task():
    logger.debug('The sample task just ran.')

并将以下内容添加到api/api/settings/base.pybase.py 被导入到api/api/settings/__init__.py)。

CELERY_BROKER_URL = 'redis://cache:6379'
CELERY_RESULT_BACKEND = 'redis://cache:6379'

CELERY_BEAT_SCHEDULE = {
    'sample_task': {
        'task': 'server.tasks.sample_task',
        'schedule': crontab(),
    },
}

cache 服务似乎启动良好(输出一堆日志,以“准备接受连接”结尾),但queuescheduler 服务似乎没有输出任何内容。当我运行docker-compose logs -f 'queue'docker-compose logs -f 'scheduler' 时,我得到以下输出。

Attaching to

我可以将sample_task() 作为 Celery 任务从 python 控制台导入并运行。

>>> from server.tasks import sample_task
>>> sample_task()
2020-09-10 13:47:15,020 server.tasks DEBUG    The sample task just ran.
>>> sample_task.delay()
<AsyncResult: 1594ed42-23d0-4302-8754-ba9097c170bd>

那我做错了什么?我错过了什么?


更新

我取得了一点进展。我一直在 PyCharm 中使用 docker run 配置到 --build 项目,并没有意识到它被设置为仅构建 web 服务;因此没有构建队列和调度程序服务。

在我修复该问题后,队列和调度程序服务正在输出抱怨未设置环境变量的日志。因此,将env_file 属性添加到这两个服务后,我现在可以附加到api_queue_1api_scheduler_1,但仍然没有进一步的输出。

【问题讨论】:

    标签: python django docker celery celerybeat


    【解决方案1】:
    command: celery -A api worker -l info
    
    logger.debug('The sample task just ran.')
    

    你看到问题了吗? ::facepalm::

    我使用 info 日志级别运行 celery,但日志输出使用 debug 日志级别,因此 debug 日志没有传播。

    我原以为我会看到 celery 的某种输出,即使是在信息日志级别,但我想不会。而且我仍然不确定为什么我在 docker 容器的 bash shell 中运行 celery 命令时会看到输出,甚至在我更改日志级别之前。

    【讨论】: