Celery-Django作为守护进程:未找到设置
通过跟着这个教程,我现在有了一个正常工作的Celery-Django应用。当我用这个命令启动工作进程时: celery -A myapp worker -n worker1.%h
在我的Django的settings.py文件中,我设置了Celery的所有参数(比如消息代理的IP地址等等)。一切运行得很好。
接下来的步骤是把这个应用作为守护进程运行。所以我又跟着这个第二个教程,一切都很简单,除了现在我在settings.py中设置的Celery参数没有加载。例如,消息代理的IP设置为127.0.0.1,但在我的settings.py中,我设置的是另一个IP地址。
在教程中,他们提到:
确保定义你Celery应用实例的模块也为DJANGO_SETTINGS_MODULE设置了默认值,具体可以参考Django入门中的示例项目。
所以我确保做了这一点。我在/etc/default/celeryd中添加了这行:
export DJANGO_SETTINGS_MODULE="myapp.settings"
但还是不行……我在/etc/init.d/celeryd中也加了这一行,结果还是不行。我不知道该怎么办了。有没有人能给点建议?
编辑: 这是我的celery.py:
from __future__ import absolute_import
import os
from django.conf import settings
from celery import Celery
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
app = Celery('myapp')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
编辑 #2: 这是我的/etc/default/celeryd:
# Names of nodes to start
# most will only start one node:
CELERYD_NODES="worker1.%h"
# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
# App instance to use
# comment out this line if you don't use an app
CELERY_APP="myapp"
# Where to chdir at start.
CELERYD_CHDIR="/home/ubuntu/myapp-folder/"
# Extra command-line arguments to the worker
CELERYD_OPTS=""
# %N will be replaced with the first part of the nodename.
CELERYD_LOG_FILE="/var/log/celery/%N.log"
CELERYD_PID_FILE="/var/run/celery/%N.pid"
# Workers should run as an unprivileged user.
# You need to create this user manually (or you can choose
# a user/group combination that already exists, e.g. nobody).
CELERYD_USER="ubuntu"
CELERYD_GROUP="ubuntu"
# If enabled pid and log directories will be created if missing,
# and owned by the userid/group configured.
CELERY_CREATE_DIRS=1
# Name of the projects settings module.
export DJANGO_SETTINGS_MODULE=myapp.settings
export PYTHONPATH=$PYTHONPATH:/home/ubuntu/myapp-folder
5 个回答
我想给最近遇到这个问题的人提供一个答案。
我按照Celery 4.4.7的入门指南和守护进程教程一步一步来,但没有成功。
我最开始遇到的问题是:
celery -A app_name worker -l info
可以正常运行(我的celery配置是没问题的)。- 我可以把celeryd作为守护进程启动,状态命令显示正常,但无法接收任务。查看日志时,我看到以下内容:
[2020-11-01 09:33:15,620: ERROR/MainProcess] consumer: 无法连接到 amqp://guest:**@127.0.0.1:5672//: [Errno 111] 连接被拒绝。
- 这说明celeryd没有连接到我的消息代理(redis)。因为我在配置中已经设置了CELERY_BROKER_URL,这意味着我的celery应用设置没有被守护进程读取到。
- 我尝试运行
sudo C_FAKEFORK=1 sh -x -l -E /etc/init.d/celeryd start
来看看我的celery设置是否被读取,结果发现app
被设置为默认的default
(而不是我在/etc/default/celeryd
中指定的CELERY_APP
的应用名)。
因为celery -A app_name worker -l info
可以正常工作,所以我通过在/etc/default/celeryd/
中导出CELERY_APP来解决了这个问题,而不是仅仅按照文档设置变量。
总结一下:
如果celery -A app_name worker -l info
可以正常运行(把app_name替换成你在Celery入门指南中定义的名称),而sudo C_FAKEFORK=1 sh -x -l -E /etc/init.d/celeryd start
没有显示你的celery应用设置被读取到,那么在/etc/default/celeryd
的末尾添加以下内容:
export CELERY_APP="app_name"
在你的第二个教程中,他们把django_settings变量设置成了:
export DJANGO_SETTINGS_MODULE="settings"
这可能是你找不到设置文件的原因,因为它可能变成了目录 "/home/ubuntu/myapp-folder/"。
然后你把你的应用定义为"myapp",接着你说设置文件在"myapp.settings"里。
这样可能导致它在以下位置寻找设置文件:
"/home/ubuntu/myapp-folder/myapp/myapp/settings"
所以我的建议是把DJANGO_SETTINGS_MODULE变量中的"myapp."去掉,别忘了引号哦。
下面这个方法并不能用来启动celeryd,而是用来把celery工作进程作为一个服务来运行,这样它会在开机时自动启动。
像这样的命令 sudo service celery status
也可以使用。
celery.conf
# This file sits in /etc/init
description "Celery for example"
start on runlevel [2345]
stop on runlevel [!2345]
#Send KILL after 10 seconds
kill timeout 10
script
#project(working_ecm) and Vitrualenv(working_ecm/env) settings
chdir /home/hemanth/working_ecm
exec /home/hemanth/working_ecm/env/bin/python manage.py celery worker -B -c 2 -f /var/log/celery-ecm.log --loglevel=info >> /tmp/upstart-celery-job.log 2>&1
end script
respawn
这个问题很可能是因为 celeryd
找不到你的 Django 设置文件,因为 myapp.settings
没有在 $PYTHONPATH
中,所以应用程序运行时找不到。
根据我的记忆,Python 在导入文件时会查看 $PYTHONPATH
和本地文件夹。当 celeryd
运行时,它可能会先检查路径中是否有一个叫 app
的模块,如果找不到,就会在当前文件夹中查找一个名为 app
的文件夹,并且这个文件夹里需要有一个 __init__.py
文件(也就是一个 Python 模块)。
我觉得你只需要在你的 /etc/default/celeryd
文件中添加以下内容:
export $PYTHONPATH:path/to/your/app
这里的所有回答都可能是解决问题的一部分,但最后还是没能成功。不过我最终还是找到了让它工作的办法。
首先,在 /etc/init.d/celeryd
文件中,我把这一行改成了:
CELERYD_MULTI=${CELERYD_MULTI:-"celeryd-multi"}
改成:
CELERYD_MULTI=${CELERYD_MULTI:-"celery multi"}
原来的那一行被标记为不推荐使用,这可能是问题所在。
此外,我还把这个作为选项加上了:
CELERYD_OPTS="--app=myapp"别忘了还要设置一些环境变量:
# Name of the projects settings module.
export DJANGO_SETTINGS_MODULE="myapp.settings"
export PYTHONPATH="$PYTHONPATH:/home/ubuntu/myapp-folder"
经过这些调整,现在在我这边已经可以正常工作了。