我正在测试一个API,它将长时间运行的作业发送到由Celery worker处理的队列中。我正在使用运行在Docker容器中的RabbitMQ作为消息队列。但是,当向队列发送消息时,我收到以下错误:Error: [Errno 111] Connection refused
重现步骤:
- 启动RabbitMQ容器:
docker run -d -p 5672:5672 rabbitmq
个 - 启动Celery服务器:
celery -A celery worker --loglevel=INFO
- 构建Docker映像:
docker build -t fastapi .
- 运行容器
docker run -it -p 8000:8000 fastapi
停靠文件:
FROM python:3.9
WORKDIR /
COPY . .
RUN pip install --no-cache-dir --upgrade -r ./requirements.txt
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
requirements.txt:
anyio==3.6.1
asgiref==3.5.2
celery==5.2.7
click==8.1.3
colorama==0.4.4
fastapi==0.78.0
h11==0.13.0
httptools==0.4.0
idna==3.3
pydantic==1.9.1
python-dotenv==0.20.0
PyYAML==6.0
sniffio==1.2.0
starlette==0.19.1
typing_extensions==4.2.0
uvicorn==0.17.6
watchgod==0.8.2
websockets==10.3
app.py:
from fastapi import FastAPI
import tasks
@app.get("/{num}")
async def root(num):
tasks.update_db.delay(num)
return {"success": True}
tasks.py:
from celery import Celery
import time
celery = Celery('tasks', broker='amqp://')
@celery.task(name='update_db')
def update_db(num: int) -> None:
time.sleep(30)
return
2条答案
按热度按时间mrphzbgm1#
您无法连接到
localhost
上的rabbitmq;它并没有运行在Python应用程序所在的容器中。既然你已经在你的主机上公开了rabbit,你就可以使用你的主机地址连接到它。一种方法是像这样启动应用程序容器:然后像这样修改代码:
准备好这些代码后,让我们重新运行您的示例:
如果你只需要从一个容器中访问rabbitmq端口,那么没有必要在你的主机上发布rabbitmq端口。当构建一个有多个容器的应用程序时,使用像docker-compose这样的工具可以让你的工作变得更容易。
如果使用了以下
docker-compose.yaml
:并修改了代码以连接到
rabbitmq
:然后你可以运行
docker-compose up
来打开两个容器,你的应用程序会在主机端口8000
上公开,但是rabbitmq只对你的应用程序容器可用。顺便说一句,您可能希望从环境变量中获取代理uri,而不是在代码中硬编码代理uri:
这样就可以使用不同的连接字符串,而不必每次都重新构建映像。我们需要修改
docker-compose.yaml
以包含适当的变量:8hhllhi22#
更新任务.py