【问题标题】:Dockerized Celery worker not picking up tasks from Localstack SQS QueueDockerized Celery worker 没有从 Localstack SQS 队列中获取任务
【发布时间】:2020-02-13 22:07:01
【问题描述】:

我正在用 celery 构建一个烧瓶应用程序来执行后台任务。我的应用程序使用在 docker 容器中运行的 localstack 来为我的消息代理在本地模拟 SQS。我已经让烧瓶和芹菜在本地运行,以便与 localstack 正常工作,我可以看到烧瓶接收请求,将消息添加到 SQS 队列,然后 celery 拿起该任务并执行它。

我已尝试将烧瓶和 celery 与 localstack 一起 dockerize,并且我的所有服务都按预期运行,除了不执行队列中任务的 celery worker。我可以在本地启动一个 celery worker 来读取队列并执行任务,但是 docker celery worker 不会拉任何任务。

在烧瓶容器中运行 celery worker 得到了相同的结果,并添加了我在 github thread 中找到的 --without-gossip 之类的参数。

我是否在 docker 架构中遗漏了使 celery 无法从 SQS 队列中拉出的东西?

这是我的 docker-compose.yml:


services:
  dev:
    build:
      context: .
      dockerfile: 'dev.Dockerfile'
    ports:
    - "5050:5000"
    restart: always
    volumes:
    - .:/app
    environment:
    - GUNICORN_CMD_ARGS="--reload"
    - docker_env=true
    stdin_open: true
    tty: true
    command: ./entrypoint.sh
    depends_on: 
      - localstack

  # mimics AWS services locally
  localstack:
    image: localstack/localstack:latest
    ports:
      - '4561-4599:4561-4599'
      - '8080:8080'
    environment:
      - SERVICES=sqs
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
    volumes:
      - './.localstack:/tmp/localstack'
    restart: always

  celery:
    build:
      context: .
      dockerfile: 'dev.Dockerfile'
    volumes:
      - .:/app
    environment: 
      - docker_env=true
    stdin_open: true
    tty: true
    command: ./celeryworker.sh
    restart: always
    links:
      - localstack
    depends_on:
      - localstack


volumes:
  .:

dev.dockerfile:

FROM python:3.6

USER root

# Environment Variables
ENV HOST 0.0.0.0
ENV PORT 5000

# Install Packages
COPY requirements.txt /requirements.txt

RUN /bin/bash -c "python3 -m venv docker \
    && source docker/bin/activate \
    && pip3 install --upgrade pip \
    && pip3 install -r requirements.txt"

# Source Code
WORKDIR /app
COPY . .
COPY app/gunicorn_config.py /deploy/app/gunicorn_config.py
COPY entrypoint.sh /bin/entrypoint.sh
COPY celeryworker.sh /bin/celeryworker.sh


USER nobody

EXPOSE 5000
CMD ["bash"]

入口点.sh:

source ../docker/bin/activate
gunicorn -c app/gunicorn_config.py --bind 0.0.0.0:5000 'app:create_app()'

celeryworker.sh

source ../docker/bin/activate
celery worker -A app.celery_worker.celery

celeryconfig.py

import os

BROKER_URL = 'sqs://fake:fake@localhost:4576/0'     # local sqs
# BROKER_URL = 'redis://localhost:6379/0'     # local redis
# RESULT_BACKEND = 'redis://localhost:6379/0'     # local redis
if os.getenv('docker_env', 'local') != 'local':
    BROKER_URL = 'sqs://fake:fake@localstack:4576/0'

BROKER_TRANSPORT_OPTIONS = {'queue_name_prefix': 'app-'}

我在本地使用相同的命令,一切都按预期运行。我还重新创建了本地虚拟环境,以确保我的 requirements.txt 中没有多余的包

【问题讨论】:

    标签: docker flask celery python-3.6 localstack


    【解决方案1】:

    通过在 localstack 环境变量中设置 HOSTNAMEHOSTNAME_EXTERNAL 解决了这个问题。通过在localhostlocalstack 之间更改两者,我可以让本地或码头芹菜工人拉动任务。

    【讨论】:

    • 有趣的设置。为什么选择使用假的 sqs 后端进行本地开发?是否无法访问 AWS sqs 队列?或者这是一个成本/谨慎的事情?
    • @MichaelDausmann 这样我们就可以开发和运行我们所有的单元测试,而无需在本地集成到其他系统。当我们部署到远程开发环境时,我们将测试我们所有的集成