Docker中部署使用了celery的Django项目阻塞问题
我有一个Django项目, 在这个项目中使用了celery执行异步任务,broker使用的是rabbitmq, 我在我的macbook运行一切正常,然后在CentOS的虚拟机中运行也没有问题,但是,当我使用docker部署这个项目时,如果我请求的一个view,这个view调用了一个celery task的daley方式时,就会被阻塞。
我创建了一个测试项目,放在我的github上: https://github.com/fengyoucha...。
Task
@shared_task
def add(x, y):
return x + y
其实还定义其他任务,但是在这个项目中的view中只调用这个task。
View
def index(request): # 映射 /
a = int(request.GET.get('a', 1))
b = int(request.GET.get('b', 2))
add.delay(a, b)
return HttpResponse("Hello world")
def hello(request): # 映射 /hello
return HttpResponse("hello")
这个项目使用了docker-compose部署,docker-compose.yml
定义了三个服务
- rabbitmq - rabbitmq 服务
- web - 执行
python mananage.py runserver 0.0.0.0:8000
- celery - 执行
celery -A proj worker -l info
使用docker-compose up
启动服务后
测试web服务
请求index
curl localhost:8000
此命令会阻塞,在index方法中的add.delay(a, b)
发生了阻塞
请求helle
curl localhost:8000/hello
返回内容“hello”, hello方法中并没有调用task的delay
方法
进一步测试
在物理机中执行启动proj这个项目,当然只启动web就行了,也就是运行python manage.py runserver
为了证明只有在docker运行web会阻塞, 这里要求其他环境都使用docker-compose.yml定义的服务
保留启动的celery和rabbit docker容器(也不用关闭docker中的web容器,其实就是什么也不需要做....)
我在docker-compose.yml中已经定义了rabbit的5672端口映射到物理机的5672端口,而在proj这个django项目中,通过读取环境变量RABBITMQ_HOST
来设置需要链接的rabbitmq server
proj中配置broker相关代码
RABBITMQ_HOST = os.environ.get("RABBITMQ_HOST", 'rabbitmq')
CELERY_BROKER_URL = 'amqp://guest:guest@%s//' % RABBITMQ_HOST
在物理机更改下环境变量,然后新起一个web
export RABBITMQ_HOST=localhost
python manage.py runserver 0.0.0.0:18000
访问该web的view
curl locahost:18000
该请求正常返回 “Hello world”, 同时celery容器中也打印出了执行add
任务的日志。
我的其他测试
我也进行了其他测试,例如:docker中启动web, 使用物理机中的rabbit,物理机中启动的celery, 一样会阻塞,
反正只要在docker中运行web,执行task的delay
方法就会发生阻塞。
最后
这个问题已经困扰很久,docker中部署使用了celery的Django项目,有谁有成功经验,或者我哪里配置有问题,望指教。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
怎么还没有人回答呢,至今为解决
我现在也遇到问题了(不过我用的是flask框架),思考celery到底要怎么和web的容器一起使用
到底是 celery容器 + web app容器 + 其他的容器这样
还是把celery整合到web app容器里面。
由于是docker新手,不知道要怎么搞成整合
不整合又想在celery里面用到sqlalchemy(web app里面定义了模型)的model。
在网上也找不到相关的例子,欸
怎么没人回答呢