【问题标题】:Daemonization celery in production生产中的守护进程芹菜
【发布时间】:2019-12-07 13:17:14
【问题描述】:

我正在尝试在 Ubuntu 18.04 中将 Celery 作为服务运行,使用安装在 env 中的 Django 2.1.1 和 Celery 4.1.1 以及在系统范围内安装的 Celery 4.1.0。我将继续使用this tutorial 将 Celery 作为服务运行。这是我的 Django 项目树:

    hamclassy-backend
                 ├── apps
                 ├── env
                 │   └── bin
                 │        └── celery
                 ├── hamclassy
                 │   ├── celery.py
                 │   ├── __init__.py
                 │   ├── settings-dev.py
                 │   ├── settings.py
                 │   └── urls.py
                 ├── wsgi.py
                 ├── manage.py
                 └── media

这里是 celery.py :

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hamclassy.settings')

app = Celery('hamclassy')

app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

这里是/etc/systemd/system/celery.service:

[Unit]
Description=Celery Service
After=network.target

[Service]
Type=forking
User=classgram
Group=www-data
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/home/classgram/www/hamclassy-backend
ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} \
  -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
  --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} \
  --pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh -c '${CELERY_BIN} multi restart ${CELERYD_NODES} \
  -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
  --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'

[Install]
WantedBy=multi-user.target


和 /etc/conf.d/celery:

CELERYD_NODES="celery-worker"

CELERY_BIN="/home/classgram/www/env/bin/celery"

# App instance to use
CELERY_APP="hamclassy"


CELERYD_MULTI="multi"
# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=8"

# %n will be replaced with the first part of the nodename.
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_LEVEL="INFO"

当我使用systemctl start celery.service 运行服务时,出现以下错误:

celery.service 的作业失败,因为控制进程退出 错误代码。请参阅“systemctl status celery.service”和“journalctl -xe” 详细介绍

当我运行sudo journalctl -b -u celery 时,会出现以下日志:

正在启动 Celery 服务... celery.service: 控制进程已退出, 代码=退出状态=200 celery.service:失败,结果为“退出代码”。 无法启动 Celery 服务。

更多信息
1) 当我使用 groups classgram 时,会出现:www-data sudo
2) 很好地激活环境后,我可以用celery -A hamclassy worker -l info 运行Celery。

谢谢

【问题讨论】:

  • 我建议您以 systemd 服务文件中指定的用户身份登录,获取环境文件,然后运行 ​​Celery worker 就像 systemd 运行它一样看看为什么会失败。
  • 感谢您的回复。错误与模块 ModuleNotFoundError: No module named 'hamclassy' 有关。当我在没有激活虚拟环境的情况下运行celery -A hamclassy worker -l info 时也会出现此错误,所以我认为服务无法运行,因为我无法在此命令之前激活虚拟环境。我该怎么做?

标签: django service celery systemctl


【解决方案1】:

好的,现在我们知道错误是什么(从您的评论中),以下几个步骤很可能会解决您的问题:

  1. 为您的 Celery 创建一个虚拟环境:python3 -m venv /home/classgram/venv

  2. 您的环境文件必须为export PYTHONPATH=/home/classgram/www/hamclassy-backend,这是最简单的解决方案,适用于测试和开发。但是,对于生产,我建议您构建一个 Python 包(wheel),并将其安装在您的虚拟环境中。

  3. 修改你的 systemd 服务文件(也可能是环境文件),这样你就可以直接从我们上面创建的 Python 虚拟环境中执行 Celery。它应该以这种方式(或类似方式)运行 Celery:/home/classgram/venv/bin/celery multi start ${CELERYD_NODES} -A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}。当然,您可以通过将 CELERY_BIN 设置为 /home/classgram/venv/bin/celery 来缩短它。

【讨论】:

  • 上帝保佑你的主人。你救了我几天。现在正在工作。我自己为 django 设置了环境,所以不需要创建新的,但我按照你告诉我的那样更改了 systemd,它现在可以工作了。
  • 我放弃了使用 celery multi,现在我在分离模式下运行单个 worker。
猜你喜欢
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2017-12-14
相关资源
最近更新 更多