Celery+Flask+Docker,消费者:无法连接到amqp://admin:**@rabbit:5672/myh



背景

我正在构建一个使用Flask作为后端框架的web应用程序。应用程序使用Celery将所有耗时的任务作为后台任务处理,以免阻塞后端线程。我使用RabbitMQ作为Celery工作人员的消息代理。我使用docker compose捆绑了每项服务。

问题

在过去的几天里,该应用程序一直运行良好,突然之间,Celery的工作人员一直无法连接到消息代理,并显示错误消息[ERROR/MainProcess] consumer: Cannot connect to amqp://admin:**@rabbit:5672/myhost: failed to resolve broker hostname.

目录结构和代码

我把文件和目录放在一起,作为一个可重复性最低的例子。

debug/
├── code
│   ├── dev.Dockerfile
│   ├── my_app
│   │   ├── celery_app.py
│   │   ├── config.py
│   │   ├── extensions.py
│   │   ├── __init__.py
│   │   ├── my_tasks.py
│   │   └── test_app.py
│   └── requirements.txt
└── docker-compose_dev.yml

docker-compose_dev.yml

version: "3.7"
services:
rabbit:
image: rabbitmq:3.8.5-management
ports:
- '15673:15672' # in case user has rabbitMQ installed on host
expose:
- "5672"
environment:
- RABBITMQ_DEFAULT_USER=admin
- RABBITMQ_DEFAULT_PASS=mypass
- RABBITMQ_DEFAULT_VHOST=myhost
non_working_worker:
build:
context: ./code
dockerfile: dev.Dockerfile
command: "celery worker -A my_app.celery_app:app -l info"
volumes:
- ./code:/code
links:
- rabbit
working_worker:
build:
context: ./code
dockerfile: dev.Dockerfile
command: "celery worker -A my_app.my_tasks:app -l info"
volumes:
- ./code:/code
links:
- rabbit

dev。Dockerfile

FROM continuumio/miniconda3
# Make /backend working directory; flask code lives here
WORKDIR /code
# Install from requirements.txt using pip
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
RUN rm requirements.txt

requirements.txt

luigi==2.8.11
plotnine==0.7.0
celery==4.4.6
flask==1.1.2
flask-cors
flask-socketio
Flask-Mail
eventlet

测试应用程序

import eventlet
eventlet.monkey_patch()
from flask import Flask
from my_app.extensions import celery
def create_app():
"""
Application factory. Create application here.
"""
app = Flask(__name__)
app.config.from_object("my_app.config")
return app
def init_celery(app=None):
"""
Initialize Celery App
"""
app = app or create_app()
app.config.from_object("my_app.config")
# Set celery worker configuration
# Use this to load config information from flask config file
celery.conf.broker_url = app.config["CELERY_BROKER_URL"]
celery.conf.result_backend = app.config["CELERY_RESULT_BACKEND"]
class ContextTask(celery.Task):
"""Make celery tasks work with Flask app context"""
def __call__(self, *args, **kwargs):
with app.app_context():
return self.run(*args, **kwargs)
celery.Task = ContextTask
return celery

配置

# RabbitMQ
CELERY_BROKER_URL='pyamqp://admin:mypass@rabbit/myhost'
CELERY_RESULT_BACKEND='rpc://'

分机.py

from celery import Celery
celery = Celery()

cele_app.py

from my_app.test_app import init_celery
app = init_celery()

my_tasks.py

from celery import Celery

app = Celery()
app.conf.broker_url = 'pyamqp://admin:mypass@rabbit/myhost'
app.conf.result_backend = 'rpc://'

我尝试过的

以下是我尝试过的事情,但没有成功。

  1. RabbitMQ没有正确启动?
    • a。它在给定用户名、密码和vhost的情况下正常启动。(可以使用管理插件@localhost:15673进行检查(
  2. RabbitMQ在Celery工人启动后启动,所以工人找不到经纪人?
    • a。Celery具有retry功能,因此它将继续重试,直到消息代理运行为止
  3. 网络问题?
    • a。我尝试过使用/不使用links来指定服务名称别名,但仍然没有成功
    • b。注意,我已经将代理名称指定为rabbit,如config.py文件中所指定的,而不是localhost
    • c。我尝试使用docker-compose创建的默认网络和自定义网络,但都失败了
  4. 有趣的是,my_tasks.py中的Celery应用程序实例可以工作(在docker compose文件中命名为working_worker(,但Flask工厂模式中的Celey应用程序实例不工作(在compose文件中将其命名为non_working_worker(
    • a。同样,它表明RabbitMQ工作得很好,但Flask工厂模式风格的Celery应用程序实例化发生了一些奇怪的事情

我花了几天的时间试图解决这个问题,并在互联网上搜索类似的问题,但没有成功。

我知道这是一个相当长的帖子,但任何帮助/建议都将不胜感激。

docker撰写版本

docker-compose version 1.25.3, build d4d1b42b
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

docker版本

Client: Docker Engine - Community
Version:           19.03.12
API version:       1.40
Go version:        go1.13.10
Git commit:        48a66213fe
Built:             Mon Jun 22 15:45:36 2020
OS/Arch:           linux/amd64
Experimental:      false
Server: Docker Engine - Community
Engine:
Version:          19.03.12
API version:      1.40 (minimum version 1.12)
Go version:       go1.13.10
Git commit:       48a66213fe
Built:            Mon Jun 22 15:44:07 2020
OS/Arch:          linux/amd64
Experimental:     false
containerd:
Version:          1.2.13
GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version:          1.0.0-rc10
GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version:          0.18.0
GitCommit:        fec3683

我遇到了一个类似的问题,通过在eventlet上面的requirements.txt中将dnspython(eventlet依赖项之一(的版本指定为1.16.0,我解决了这个问题。看起来eventlet与最新版本的dnspython不兼容,更多信息请点击此处https://github.com/eventlet/eventlet/issues/619

相关内容

  • 没有找到相关文章

最新更新