Dockerized Celery worker 没有从 Localstack SQS 队列中获取任务
Dockerized Celery worker not picking up tasks from Localstack SQS Queue
我正在用 celery 构建一个用于后台任务的烧瓶应用程序。我的应用程序在 docker 容器中使用 localstack 运行ning 来为我的消息代理在本地模拟 SQS。我已经在本地安装了 flask 和 celery 运行ning 以与 localstack 一起正常工作,在那里我可以看到 flask 收到一个请求,向 SQS 队列添加一条消息,然后 celery 获取该任务并执行它。
我已经尝试 docker 将 flask 和 celery 以及 localstack 和我的所有服务 运行 按预期进行处理,除了 celery worker 不执行队列中的任务。我可以在本地启动一个 celery worker 来读取队列并执行任务,但是 docker celery worker 不会执行任何任务。
运行 flask 容器中的 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"]
entrypoint.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
中没有额外的包
通过在 localstack 环境变量中设置 HOSTNAME
和 HOSTNAME_EXTERNAL
解决了这个问题。通过在 localhost
和 localstack
之间更改两者,我可以获得本地或 docker 芹菜工人拉取任务。
与 Celery 相关,但使用 S3 而不是 SQS,这取决于请求是在主机上处理还是在 docker 服务中处理,AWS 客户端可能需要使用端点 URL 明确地。
例如在 Python 使用 boto3
:
# client instantiated from within Celery service running as a Docker service:
client = boto3.client(
service_name="s3",
endpoint_url="http://localstack:4566", # <= localstack
)
# client instantiated in application, whether running on host or
# as Docker service
client = boto3.client(
service_name="s3",
endpoint_url="http://localhost:4566", # <= localhost
)
我正在用 celery 构建一个用于后台任务的烧瓶应用程序。我的应用程序在 docker 容器中使用 localstack 运行ning 来为我的消息代理在本地模拟 SQS。我已经在本地安装了 flask 和 celery 运行ning 以与 localstack 一起正常工作,在那里我可以看到 flask 收到一个请求,向 SQS 队列添加一条消息,然后 celery 获取该任务并执行它。
我已经尝试 docker 将 flask 和 celery 以及 localstack 和我的所有服务 运行 按预期进行处理,除了 celery worker 不执行队列中的任务。我可以在本地启动一个 celery worker 来读取队列并执行任务,但是 docker celery worker 不会执行任何任务。
运行 flask 容器中的 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"]
entrypoint.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
通过在 localstack 环境变量中设置 HOSTNAME
和 HOSTNAME_EXTERNAL
解决了这个问题。通过在 localhost
和 localstack
之间更改两者,我可以获得本地或 docker 芹菜工人拉取任务。
与 Celery 相关,但使用 S3 而不是 SQS,这取决于请求是在主机上处理还是在 docker 服务中处理,AWS 客户端可能需要使用端点 URL 明确地。
例如在 Python 使用 boto3
:
# client instantiated from within Celery service running as a Docker service:
client = boto3.client(
service_name="s3",
endpoint_url="http://localstack:4566", # <= localstack
)
# client instantiated in application, whether running on host or
# as Docker service
client = boto3.client(
service_name="s3",
endpoint_url="http://localhost:4566", # <= localhost
)