Python3.10环境Django Celery自动重载调用pkill报错如何解决
报错原因
你使用的python:3.10.0-slim-buster属于Debian精简版镜像,为了控制镜像体积默认没有预装procps系统工具包,而你代码中用到的pkill命令包含在该工具包中,因此执行时触发了文件不存在的报错。
解决方案
你可以选择以下任意一种方式解决问题:
方案1:在Docker镜像中安装procps工具包
修改你的Dockerfile,在安装Python依赖的步骤前新增系统包安装逻辑,示例如下:
FROM python:3.10.0-slim-buster ENV LANG C.UTF-8 ENV DEBIAN_FRONTEND=noninteractive # 新增行:安装pkill依赖的procps包,同时清理apt缓存缩小镜像体积 RUN apt-get update && apt-get install -y --no-install-recommends procps && rm -rf /var/lib/apt/lists/* RUN mkdir -m 775 /code ENV PYTHONUNBUFFERED=1 ENV PYTHONPATH=/code WORKDIR /code RUN python3 -m pip install --upgrade pip setuptools RUN pip install pipenv COPY Pipfile ./ RUN pipenv lock --python /usr/local/bin/python RUN pipenv install --system --deploy --dev COPY app /code
重新构建镜像后即可正常使用pkill命令。
方案2:修改Python代码,不依赖系统pkill命令
使用跨平台的进程管理库psutil实现Celery进程的终止,不需要额外安装系统工具:
- 首先将
psutil加入你的依赖文件Pipfile并安装 - 修改自定义管理命令的代码如下:
""" Celery worker autoreload command for development """ import shlex import subprocess import psutil from django.core.management.base import BaseCommand from django.utils import autoreload def restart_celery_worker(): # 替换pkill的逻辑,遍历进程杀掉celery进程 for proc in psutil.process_iter(['cmdline']): try: if 'celery' in ' '.join(proc.info['cmdline']): proc.kill() except (psutil.NoSuchProcess, psutil.AccessDenied): pass cmd = "celery -A my_app.celery_app worker -l info --concurrency=2" subprocess.call(shlex.split(cmd)) class Command(BaseCommand): def handle(self, *args, **options): print("Starting celery worker with autoreload...") autoreload.run_with_reloader(restart_celery_worker)
注意:该自动重载功能仅建议在开发环境使用,生产环境请使用官方推荐的进程管理工具部署Celery。
内容的提问来源于stack exchange,提问作者briancaffey
相关产品推荐
相关产品推荐

