我的情况是:我正在开发一些docker容器。其中一个容器是 celery 应用程序,它从另一个应用程序获取一些任务并处理这些任务。
当我在容器中处理所有内容时,我需要在容器上进行调试,并且当代码更改时我还需要重新加载应用程序。
我可以使用 debugpy 进行调试,使用 watchmedo 进行重新加载,使这两件事分别工作。当我尝试将两者结合起来时,我的问题就出现了:在 celery 中调试+重新加载。
额外信息: 我已经有了一个 Flask 应用程序容器,只需使用 debugpy 即可实现此目的。我不需要 watchmedo 也不需要 inotify 因为 Flask 已经带有 --reload 选项。好的!但 celery 不会发生这种情况,因为它的旧 --autoreload 选项不久前已被删除。
调试:
为了实现调试,我在 dockerfile 中进行了以下操作:
CMD ["python", "-m", "debugpy", "--wait-for-client", "--listen", "0.0.0.0:9999", "-m", "celery", "-A", "celery_main", "worker", "-l", "INFO", "-n", "worker", "--concurrency=1"]
工作正常,但代码更改时不会重新加载。
重新加载:
为了实现重新加载,我在 dockerfile 中做了以下操作。
CMD ["watchmedo" "shell-command" "--patterns" "'*.py'" "--recursive" "--command='celery -A celery_main worker -l INFO -n worker --concurrency=1'"]
重新加载也很好,但我错过了调试。
尝试:混合
所以我尝试混合这两种东西,但似乎不起作用。我什么也没得到:
CMD ["watchmedo" "shell-command" "--patterns" "'*.py'" "--recursive" "--command='python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m celery -A celery_main worker -l INFO -n worker --concurrency=1'"]
顺便说一句,如果这最终起作用,我想会出现一个问题,那就是每次代码更改时,整个 debugpy... 命令都会被执行,这意味着我必须在 VSCODE 的 IDE 上重新运行调试器。
知道如何解决这个问题吗?
尝试下面的CMD:
CMD python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m watchdog.watchmedo 自动重启 -d src_dir/ -p '*.py' --recursive -- celery -A celery_main 工作线程-l 信息
我无法让 watchmedo + debugpy 为 celery 工作人员工作。但是,如果您使用的是 Django,here 描述了一些可行的东西。
基本上,创建一个包含以下内容的文件
worker.py
:
import django
# ❗ needs to be called *before* importing autoreload
django.setup()
from django.utils import autoreload
def run_celery():
# ↓ import the Celery app object from your code
from my_package.celery.app import app as celery_app
# ↓ usual celery arguments
args = "-A my.package.worker worker -l info -P solo --queues a,b"
celery_app.worker_main(args.split(" "))
print("Starting celery worker with autoreload...")
autoreload.run_with_reloader(run_celery)
一旦完成,请使用此命令:
sh -c "pip install debugpy && python -m debugpy --listen 0.0.0.0:3000 worker.py"
原始文章有更多信息,请查看如何自动重新加载和调试在 Docker 中运行的 Django 和 Django Celery 工作人员(VS Code)