Daemonization
大多数Linux发行版使用systemd来管理系统及用户服务的生命周期。
你可以使用下面的命令检查自己的发行版是否支持systemd:
$ systemd --version
systemd 237
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid
如果输出和上面的类似,请从我们的 systemd 文档获取指导
然而,init.d脚本仍然可以在这些Linux发行版中工作,因为systemd提供了systemd-sysv兼容层,该层可以从我们提供的init.d脚本自动生成服务。
如果你的Celery需要运行在不同的发行版,其中有些不支持systemd或者其他Unix系统,你可能需要我们的init.d文档
Generic init-script: 生成init脚本
查看Celery发行版中的extra/generic-init.d/目录。
这个目录包含生成init-scripts的脚本,可以在Linux、FreeBSD、OpenBSD以及其他类Unix平台运行。
Init-script: celeryd
**Usage:/etc/init.d/celeryd {start|stop|restart|status}
Configuration file: /etc/default/celeryd
要配置改脚本正常运行worker,你至少需要告诉它在启动时将目录更改到何处(去那儿查找包含应用程序的模块或配置模块)
守护进程脚本通过/etc/default/celeryd
文件进行配置。这是一个shell脚本,你可以想下面一样添加环境变量。要添加影响worker的真实的环境变量,还必须export它们(比如:export DISPLAY=":0")
Superuser privileges required:
init-scripts只能被root用户使用,并且shell配置文件也必须属于root用户。
无权限的用户无需使用init-script,他们可以使用celery multi 工具(或者 celery worker --detach
$ celery -A proj multi start worker1 \
--pidfile="$HOME/run/celery/%n.pid" \
--logfile="$HOME/log/celery/%n%I.log"
$ celery -A proj multi restart worker1 \
--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
##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"
## Configure node-specific settings by appending node name to arguments:
##CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"
## 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
Using a login shell
你可以使用登录的shell继承CELERYD_USER
的环境:
You can inherit the environment of the CELERYD_USER
by using a login shell:
CELERYD_SU_ARGS="-l"
请注意,不建议使用此选项,并且您应该仅在绝对必要时使用此选项。
PS:有兴趣的可以自己试试,由于没有详细解释,没看懂要说什么。我懒得实验
Django配置示例
Django users now uses the exact same template as above, but make sure that the module that defines your Celery app instance also sets a default value for DJANGO_SETTINGS_MODULE`` as shown in the example Django project in First steps with Django.
可用选项
CELERY_APP
要使用的APP实例(--app参数的值)
CELERY_BIN
Celery程序的绝对路径。比如:
- celery
/usr/local/bin/celery
/virtualenvs/proj/bin/celery
/virtualenvs/proj/bin/python -m celery
CELERYD_NODES
要启动的节点名称列表(用空格分隔)。
CELERYD_OPTS
worker的命令行附加参数,使用 celery worker --help 查看。它还支持扩展语法 multi 配置各个节点的设置。通过
celery multi –help
查看一些multi-node配置示例。CELERYD_CHDIR
简单理解为工作目录,默认是当前目录。
CELERYD_PID_FILE
PID文件的完整路径,默认是
/var/run/celery/%n.pid
CELERYD_LOG_FILE
worker的日志文件的完整路径。默认是
/var/log/celery/%n%I.log
Note : 使用%I
是很重要的当使用了prefork pool的时候,因为让多个进程共享同一个日志文件将导致争用情况。CELERYD_LOG_LEVEL
日志等级,默认是INFO
CELERYD_USER
运行worker的用户,默认是当前用户
CELERYD_GROUP
运行worker的组,默认是当前组
CELERY_CREATE_DIRS
总是创建目录(日志目录及PID文件目录)。默认是仅在未设置自定义 logfile/pidfile 时创建。
CELERY_CREATE_RUNDIR
总是创建pidfile目录。默认情况下,仅在未设置自定义pidfile位置时启用。
CELERY_CREATE_LOGDIR
总是创建日志文件目录。默认情况下,仅在未设置自定义日志文件位置时启用。
Init-script:celerybeat
**Usage:/etc/init.d/celerybeat {start|stop|restart}
Configuration file: /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示例配置
You should use the same template as above, but make sure the DJANGO_SETTINGS_MODULE
variable is set (and exported), and that CELERYD_CHDIR
is set to the projects directory:
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
CELETYBEAT_LOG_LEVEL
日志等级,默认是INFO
CELERYBEAT_USER
运行beat的用户,默认是当前用户
CELERYBEAT_GROUP
运行beat的组,默认是当前组
CELERY_CREATE_DIRS
总是创建目录(日志目录及PID文件目录)。默认是仅在未设置自定义 logfile/pidfile 时创建。
CELERY_CREATE_RUNDIR
总是创建pidfile目录。默认情况下,仅在未设置自定义pidfile位置时启用。
CELERY_CREATE_LOGDIR
总是创建日志文件目录。默认情况下,仅在未设置自定义日志文件位置时启用。
故障排除
如果init-scripts无法正常工作,可以尝试使用调试模式:
## sh -x /etc/init.d/celeryd start
这可以显示有关服务无法启动的原因的提示。
如果worker启动显示"OK",但很快退出并且没有日志输出,那么可能有一个错误,但是由于守护进程的标准输出已经关闭,您将无法在任何地方看到它们。在这种情况下,可以使用C_FAKEFORK
环境变量跳过后台进程化步骤
## C_FAKEFORK=1 sh -x /etc/init.d/celeryd start
现在您应该能够看到错误了。
通常,此类错误是由于权限导致。或者语法错误、拼写错误之类的。当然,如果发现了BUG可以在这里提交
Usage systemd
Usage:systemctl {start|stop|restart|status} celery.service
Configuration file: /etc/conf.d/celery
Service file: 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 -c '${CELERY_BIN} -A $CELERY_APP multi start $CELERYD_NODES \
--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} --logfile=${CELERYD_LOG_FILE} \
--loglevel="${CELERYD_LOG_LEVEL}"'
ExecReload=/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi restart $CELERYD_NODES \
--pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} \
--loglevel="${CELERYD_LOG_LEVEL}" $CELERYD_OPTS'
Restart=always
[Install]
WantedBy=multi-user.target
当你将文件放入/etc/systemd/system
时,记得执行systemctl daemon-reload
,每次更改之后也应该执行。使用systemctl enable celery.service
命令开启开机自启。
可以指定额外的依赖关系,比如你使用RabbitMQ作为broker,则应该在[Unit]
段指定After
和Requires
等于rabbitmq-server.service
。See:systemd
要设置user、group、chdir的话,在/etc/systemd/system/celery.service
文件中使用User
、Group
以及WorkingDirectory
进行配置。
或者也可以使用systemd-tmpfiles来创建工作目录(for logs and pid)
file: /etc/tmpfiles.d/celery.conf
d /run/celery 0755 celery celery -
d /var/log/celery 0755 celery celery -
示例配置
这是给一个Python项目准备的示例配置:
/etc/conf.d/
:
## 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"
## 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"
## 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_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"
## you may wish to add these options for Celery Beat
CELERYBEAT_PID_FILE="/var/run/celery/beat.pid"
CELERYBEAT_LOG_FILE="/var/log/celery/beat.log"
Service file: celerybeat.service
这是Celery Beat的示例systemd文件:
/etc/systemd/system/celerybeat.service
[Unit]
Description=Celery Beat Service
After=network.target
[Service]
Type=simple
User=celery
Group=celery
EnvironmentFile=/etc/conf.d/celery
WorkingDirectory=/opt/celery
ExecStart=/bin/sh -c '${CELERY_BIN} -A ${CELERY_APP} beat \
--pidfile=${CELERYBEAT_PID_FILE} \
--logfile=${CELERYBEAT_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL}'
Restart=always
[Install]
WantedBy=multi-user.target
当你将文件放入/etc/systemd/system
时,记得执行systemctl daemon-reload
,每次更改之后也应该执行。使用systemctl enable celery.service
命令开启开机自启。
以Root权限运行worker
以Root运行很危险,默认情况下会闪退。如果执意如此,需要使用C_FORCE_ROOT
Running the worker with superuser privileges is a very dangerous practice. There should always be a workaround to avoid running as root. Celery may run arbitrary code in messages serialized with pickle - this is dangerous, especially when run as root.
By default Celery won’t run workers as root. The associated error message may not be visible in the logs but may be seen if C_FAKEFORK
is used.
To force Celery to run workers as root use C_FORCE_ROOT
.
When running as root without C_FORCE_ROOT
the worker will appear to start with “OK” but exit immediately after with no apparent errors. This problem may appear when running the project in a new development or production environment (inadvertently) as root.