我的 Flask 应用程序由四个容器组成:Web 应用程序、postgres、rabbitMQ 和 Celery。 由于我有定期运行的芹菜任务,因此我使用芹菜节拍。 我已经像这样配置了我的 docker-compose 文件:
version: '2'
services:
rabbit:
# ...
web:
# ...
rabbit:
# ...
celery:
build:
context: .
dockerfile: Dockerfile.celery
我的 Dockerfile.celery 看起来像这样:
# ...code up here...
CMD ["celery", "-A", "app.tasks.celery", "worker", "-B", "-l", "INFO"]
虽然我在文档中读到我不应该使用
-B
选项进入生产环境,但我还是匆忙添加了它(并且忘记了更改它),并很快了解到我的计划任务正在运行多次。 对于那些感兴趣的人,如果您在 celery 容器中执行 ps aux | grep celery
,您将看到多个 celery + Beat 进程正在运行(但应该只有一个 Beat 进程和多个工作进程)。 我从文档中不确定为什么你不应该在生产中运行 -B
,但现在我知道了。
然后我将 Dockerfile.celery 更改为:
# ...code up here...
CMD ["celery", "-A", "app.tasks.celery", "worker", "-l", "INFO"]
CMD ["celery", "-A", "app.tasks.celery", "beat", "-l", "INFO"]
不,当我启动应用程序时,工作进程会启动,但beat不会启动。 当我翻转这些命令以便首先调用beat时,然后beat启动但工作进程不会启动。 所以我的问题是:如何在容器中同时运行 celeryworker +beat? 我已经梳理了很多文章/文档,但我仍然无法弄清楚这一点。
已编辑
我将 Dockerfile.celery 更改为以下内容:
ENTRYPOINT [ "/bin/sh" ]
CMD [ "./docker.celery.sh" ]
我的 docker.celery.sh 文件如下所示:
#!/bin/sh -ex
celery -A app.tasks.celery beat -l debug &
celery -A app.tasks.celery worker -l info &
但是,我收到错误
celery_1 exited with code 0
编辑#2
我将以下阻止命令添加到 docker.celery.sh 文件的末尾,所有内容都已修复:
tail -f /dev/null
docker只运行一个CMD,因此只执行第一个CMD,解决方法是创建一个执行worker和beat的bash脚本,并使用docker CMD来执行该脚本
我通过按照上面的说明放入入口点,加上我添加了 &> 将输出保存在日志文件中。
我的入口点.sh
#!/bin/bash
python3 manage.py migrate
python3 manage.py migrate catalog --database=catalog
python manage.py collectstatic --clear --noinput --verbosity 0
# Start Celery Workers
celery worker --workdir /app --app dri -l info &> /log/celery.log &
# Start Celery Beat
celery worker --workdir /app --app dri -l info --beat &> /log/celery_beat.log &
python3 manage.py runserver 0.0.0.0:8000
这对我有用
CMD ["sh", "-c", "celery -A celery_service.tasks.celery beat -l INFO --scheduler sqlalchemy_celery_beat.schedulers:DatabaseScheduler & celery -A celery_service.tasks.celery worker -l INFO -c 1 -P eventlet & tail -f /dev/null"]