Python中Celery worker启动路径问题如何解决?
django 项目,例如在 /test/server/目录下执行 python manage.py celery worker -l info -c 30 -Ofair
启用了 30 个 worker,使用 pwdx 查看某个 worker 工作路径,显示在 /test/server,一切正常。
因为系统设置了 CELERYD_MAX_TASKS_PER_CHILD = 40 参数,也就是每个 worker 最多接收 40 次任务后就销毁重建。
重建的 worker 使用 pwdx 或者 ls -l /proc/pid/ 方式查看,发现 cwd 目录并不是上述的 /test/server,而是某个任务中曾经读写过的路径。
很奇怪这种现象,使用 CELERYD_CHDIR='/test/server/' 是否就能解决这个问题呢?
Python中Celery worker启动路径问题如何解决?
这个问题我遇到过,核心是Celery的启动路径和工作目录不一致导致的模块导入失败。
根本原因:Celery worker启动时,Python的sys.path是基于你执行celery -A命令的当前工作目录(CWD)来解析模块路径的。如果你的项目结构复杂,或者你从项目根目录以外的位置启动worker,就会找不到任务模块。
解决方案(按推荐度排序):
-
标准做法:从项目根目录启动 这是最可靠的方式。确保你的项目结构清晰,并在根目录下启动worker。
# 假设你的项目结构如下: # myproject/ # celery_app.py # tasks/ # __init__.py # email_tasks.py # 在myproject/目录下执行: celery -A celery_app worker --loglevel=info -
使用绝对模块路径(推荐) 在定义Celery应用时,使用完整的导入路径。
# celery_app.py from celery import Celery # 使用绝对导入路径,而不是相对路径 app = Celery('myproject', broker='redis://localhost:6379/0', include=['myproject.tasks.email_tasks']) # 关键在这里 -
设置PYTHONPATH环境变量 如果你必须从其他目录启动,可以临时设置Python路径。
# Linux/Mac export PYTHONPATH=/path/to/your/project celery -A celery_app worker --loglevel=info # Windows (cmd) set PYTHONPATH=C:\path\to\your\project celery -A celery_app worker --loglevel=info -
在代码中动态修改sys.path(备选) 作为最后手段,可以在Celery应用文件开头添加路径。
import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) from celery import Celery app = Celery('myproject')
一句话总结:从项目根目录启动worker并使用绝对导入路径是最佳实践。

