Celery教程————-以守护进程方式运行worker

2023年7月27日11:05:45

celery不能以守护进程方式运行自己,需要使用下面的工具:

通用的初始化脚本 

脚本代码:extra/generic-init.d/ 

这个目录包含了celery worker程序通用的初始化脚本,这些脚本应该运行在Linux,FreeBSD,OpenBSD和其它类UNIX平台。


初始化脚本:celeryd

使用方法:/etc/init.d/celeryd {start|stop|restart|status}

配置文件:/etc/default/celeryd

要配置这个脚本能够正常运行你的worker,你至少需要配置worker启动后需要使用的目录(查找包含app的模块和你的配置模块)。

worker守护化的配置脚本为/etc/default/celeryd,这是一个shell脚本。你可以为这个脚本添加环境变量和配置选项。添加了环境变量之后,你必须export它们(比如 export DISPLAY=":0")。


需要管理员权限

初始化脚本和配置脚本必须使用root用户。

权限不足的用户不能够使用初始化脚本,他们可以使用celery multi工具(或者celery worker --detach)。

$ celery multi start worker1 \
    -A proj \
    --pidfile="$HOME/run/celery/%n.pid" \
    --logfile="$HOME/log/celery/%n%I.log"

$ celery multi restart worker1 \
    -A proj \
    --logfile="$HOME/log/celery/%n%I.log" \
    --pidfile="$HOME/run/celery/%n.pid

$ celery multi stopwait worker1 --pidfile="$HOME/run/celery/%n.pid"

配置举例

这是一个python工程的配置举例

/etc/default/celeryd

# Names of nodes to start
#   most people will only start one node:
CELERYD_NODES="worker1"
#   but you can also start multiple and configure settings
#   for each in CELERYD_OPTS (see `celery multi --help` for examples):
#CELERYD_NODES="worker1 worker2 worker3"
#   alternatively, you can specify the number of nodes to start:
#CELERYD_NODES=10

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"

# App instance to use
# comment out this line if you don't use an app
CELERY_APP="proj"
# or fully qualified:
#CELERY_APP="proj.tasks:app"

# Where to chdir at start.
CELERYD_CHDIR="/opt/Myproject/"

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

# Set logging level to DEBUG
#CELERYD_LOG_LEVEL="DEBUG"

# %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"

# 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="celery"
CELERYD_GROUP="celery"

# If enabled pid and log directories will be created if missing,
# and owned by the userid/group configured.
CELERY_CREATE_DIRS=1

使用登陆shell

你可以通过使用登陆shell来继承CELERYD_USER环境变量。

CELERYD_SU_ARGS="-l"

注意,并不建议这样使用,只有当必须这样做时再这样使用。


Django配置举例

Django用户现在可以使用上面示例的模版,但是要确保定义celery app实例的模块也为DJANGO_SETTINGS_MODULE设置了一个默认值,可以参考: First steps with Django.


可用的选项

CELERY_APP

使用的app实例(app参数的值).如果你还在使用老的API或者django-celery,你可以省略这个配置。

CELERY_BIN

celery程序的绝对或者相对路径.比如:

  • celery
  • /usr/local/bin/celery
  • /virtualenvs/proj/bin/celery
  • /virtualenvs/proj/bin/python -m celery

CELERY_NODES

启动的节点列表(以空格分隔)

CELERY_OPTS

worker的其它命令行参数,通过celery -help查看参数列表。这个选项还支持multi的扩展语法用来配置私有节点的配置。通过celery multi --help来查看多节点的的配置举例。

CELERY_CHDIR

启动后改变到的目录,默认为当前目录。

CELERYD_PID_FILE

PID文件的全路径,默认为/var/run/celery/%n.pid

CELERY_LOG_FILE

worker日志文件的全路径。默认为/var/log/celery/%n%I.log.注意:使用%I是重要的,因为prefork池中的多个进程如果使用相同的日志文件将会产生竞争。

CELERY_LOG_LEVEL

worker的日志级别,默认为INFO

CELERYD_USER

运行worker的用户,默认为当前用户

CELERYD_GROUP

运行worker的组,默认为当前组

CELERY_CREATE_DIRS

总是创建目录(日志目录和pid文件目录)。默认只在指定了logfile/pidfile时创建目录。

CELERY_CREATE_RUNDIR

总是创建pidfile目录,默认只在指定了pidfile位置时创建。

CELERY_CREATE_LOGDIR

总是创建logfile目录,默认只在指定logfile位置时创建。


初始化脚本:celerybeat

使用方法: 

/etc/init.d/celerybeat {start|stop|restart}


配置文件:

/etc/default/celerybeat or /etc/default/celeryd

配置举例:

这是一个python工程的配置举例

/etc/default/celerybeat

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"

# App instance to use
# comment out this line if you don't use an app
CELERY_APP="proj"
# or fully qualified:
#CELERY_APP="proj.tasks:app"

# Where to chdir at start.
CELERYBEAT_CHDIR="/opt/Myproject/"

# Extra arguments to celerybeat
CELERYBEAT_OPTS="--schedule=/var/run/celery/celerybeat-schedule"

Django配置举例

你需要使用上面的配置模版,但是要保证DJANGO_SETTINGS_MODULE变量已经设置(而且export),还有CELERYD_CHDIR在工程目录设置:

export DJANGO_SETTINGS_MODULE="settings"

CELERYD_CHDIR="/opt/MyProject"

可用的选项

CELERY_APP

使用的app实例(app参数的值).

CELERYBEAT_OPTS

celery beat的附加参数,通过celery beat --help查看完整的选项列表.

CELERYBEAT_PID_FILE

PID文件的全路径,默认为/var/run/celeryd.pid

CELERYBEAT_LOG_FILE

日志文件的全路径。默认为/var/log/celeryd.log.

CELERYBEAT_LOG_LEVEL

日志级别,默认为INFO

CELERYBEAT_USER

运行beat的用户,默认为当前用户

CELERYBEAT_GROUP

运行beat的组,默认为当前组

CELERY_CREATE_DIRS

总是创建目录(日志目录和pid文件目录)。默认只在指定了logfile/pidfile时创建目录。

CELERY_CREATE_RUNDIR

总是创建pidfile目录,默认只在指定了pidfile位置时创建。

CELERY_CREATE_LOGDIR

总是创建logfile目录,默认只在指定logfile位置时创建。

问题排查

如果你不能让初始化脚本正常运行,你可以尝试以详细模式来运行:

# sh -x /etc/init.d/celeryd start

这会显示一些为什么不能运行的的提示信息

如果worker启动时显示ok,但是很快就退出了,这样日志文件中不会有任何信息,可能启动过程中有错误。但是以守护进程方式运行时,标准输出被关闭了,你就看不到任何信息了。如果遇到这种情况,你可以使用C_FAKEFORK环境变量来跳过守护进程方式:

# C_FAKEFORK=1 sh -x /etc/init.d/celeryd start

这样你就可以看到错误了。

通常情况下,错误是由于读或者写文件权限不足造成的,也有可能是配置模块,用户模块或者第三库中有语法错误,甚至是celery自身的错误(如果你发现了bug,请报告它)


使用systemd

使用方法:
systemctl {start|stop|restart|status} celery.service

配置文件:

/etc/conf.d/celery

服务文件:celery.service

这是一个systemd文件的举例:

/etc/systemd/system/celery.service:

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

[Service]
Type=forking
User=celery
Group=celery
EnvironmentFile=-/etc/conf.d/celery
WorkingDirectory=/opt/celery
ExecStart=/bin/sh '${CELERY_BIN} multi start $CELERYD_NODES \
  -A $CELERY_APP --logfile=${CELERYD_LOG_FILE} \
  --pidfile=${CELERYD_PID_FILE} $CELERYD_OPTS'
ExecStop=/bin/sh '${CELERY_BIN} multi stopwait $CELERYD_NODES \
  --pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh '${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/systemd/system目录后,你需要运行systemctl daemon-reload来让systemd识别这个文件。在你修改了这个文件后,你也需要重新运行这个命令。

要配置用户,组,chdir等配置,请修改配置文件中的User,Group,WorkingDirectory选项。

你还可以使用systemd-tmpfiles来创建工作目录(用于日志和pid)

文件:/etc/tmpfiles.d/celery.conf:

d /var/run/celery 0755 celery celery -
d /var/log/celery 0755 celery celery -

配置举例

下面是一个python工程的配置举例

/etc/conf.d/celery:

# Name of nodes to start
# here we have a single node
CELERYD_NODES="w1"
# or we could have three nodes:
#CELERYD_NODES="w1 w2 w3"

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/usr/local/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"

# How to call manage.py
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.
# - %I will be replaced with the current child process index
#   and is important when using the prefork pool to avoid race conditions.
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"

Django配置举例

下面是一个使用django-celery的配置举例:

# Name of nodes to start
# here we have a single node
CELERYD_NODES="w1"
# or we could have three nodes:
#CELERYD_NODES="w1 w2 w3"

# Absolute path to "manage.py"
CELERY_BIN="/opt/Myproject/manage.py"

# How to call manage.py
CELERYD_MULTI="celery 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.
# - %I will be replaced with the current child process index
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"

通过在celery.services里使用环境变量来添加类似DJANGO_SETTINGS_MODULE的环境变量。


以超级用户(root)身份运行worker:

以超级用户身份运行worker是一个非常危险的举动。总会有一种解决方案来避免使用root。Celery在用pickle作消息序列化时可能运行任意的代码----------这很危险,尤其是用root用户时。

默认情况下,celery不会用root用户运行worker.相关的错误信息在日志可能不可见,除非你使用了C_FAKEFORK。

使用C_FORCE_ROOT来强制celery使用root用户来运行worker。

当使用C_FORCE_ROOT来运行worker时,可能会出现"OK"后直接退出且没有任何错误的情况。这可能是由于不经意间使用root用户运行工程在一个新的开发环境或者生产环境。

下面有一个非常好的外部教程:

http://www.calazan.com/windows-tip-run-applications-in-the-background-using-task-scheduler/

  • 作者:self-motivation
  • 原文链接:https://blog.csdn.net/happyAnger6/article/details/51626516
    更新时间:2023年7月27日11:05:45 ,共 7179 字。