守护进程 — Python 文档
守护进程
现在大多数 Linux 发行版都使用 systemd 来管理系统和用户服务的生命周期。
您可以通过键入以下内容来检查您的 Linux 发行版是否使用 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 脚本中自动生成服务。
如果您为多个 Linux 发行版打包 Celery,并且有些不支持 systemd 或其他 Unix 系统,您可能需要参考 我们的 init.d 文档 。
通用初始化脚本
参见 extra/generic-init.d/ 目录 Celery 发行版。
该目录包含用于 celery worker 程序的通用 bash 初始化脚本,这些脚本应该在 Linux、FreeBSD、OpenBSD 和其他类 Unix 平台上运行。
初始化脚本:celeryd
- 用法
- /etc/init.d/celeryd {开始|停止|重启|状态}
- 配置文件
/etc/default/celeryd
要配置此脚本以正确运行工作程序,您可能至少需要告诉它在启动时将目录更改到何处(以查找包含您的应用程序的模块或配置模块)。
守护进程脚本由文件 /etc/default/celeryd
配置。 这是一个 shell (sh) 脚本,您可以在其中添加环境变量,例如下面的配置选项。 要添加影响 worker 的真实环境变量,您还必须导出它们(例如,export DISPLAY=":0")
需要超级用户权限
init-scripts 只能由 root 使用,shell 配置文件也必须由 root 拥有。
非特权用户不需要使用 init 脚本,而是可以使用 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
使用登录外壳
您可以使用登录shell继承CELERYD_USER
的环境:
CELERYD_SU_ARGS="-l"
请注意,不建议这样做,并且您应该只在绝对必要时使用此选项。
Django 配置示例
Django 用户现在使用与上述完全相同的模板,但请确保定义 Celery 应用程序实例的模块也为 DJANGO_SETTINGS_MODULE
设置了默认值,如 [ X215X]Django 的第一步。
可用选项
CELERY_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。
CELERYD_CHDIR
开始时更改目录的路径。 默认是留在当前目录中。
CELERYD_PID_FILE
PID 文件的完整路径。 默认为 /var/run/celery/%n.pid
CELERYD_LOG_FILE
工作日志文件的完整路径。 默认为 /var/log/celery/%n%I.log Note:使用 %I 在使用 prefork 池时很重要,因为多个进程共享相同的日志文件会导致竞争条件。
CELERYD_LOG_LEVEL
工作日志级别。 默认为信息。
CELERYD_USER
运行工作程序的用户。 默认为当前用户。
CELERYD_GROUP
运行工人的组。 默认为当前用户。
CELERY_CREATE_DIRS
始终创建目录(日志目录和 pid 文件目录)。 默认为仅在未设置自定义日志文件/pidfile 时创建目录。
CELERY_CREATE_RUNDIR
始终创建 pidfile 目录。 默认情况下仅在未设置自定义 pidfile 位置时启用。
CELERY_CREATE_LOGDIR
始终创建日志文件目录。 默认情况下仅在未设置自定义日志文件位置时启用。
初始化脚本:celerybeat
- 用法
- /etc/init.d/celerybeat {开始|停止|重启}
- 配置文件
/etc/default/celerybeat
或/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
变量,并且将 CELERYD_CHDIR
设置为项目目录:
export DJANGO_SETTINGS_MODULE="settings"
CELERYD_CHDIR="/opt/MyProject"
可用选项
CELERY_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 as。 默认为当前用户。
CELERYBEAT_GROUP
组跑节拍。 默认为当前用户。
CELERY_CREATE_DIRS
始终创建目录(日志目录和 pid 文件目录)。 默认为仅在未设置自定义日志文件/pidfile 时创建目录。
CELERY_CREATE_RUNDIR
始终创建 pidfile 目录。 默认情况下仅在未设置自定义 pidfile 位置时启用。
CELERY_CREATE_LOGDIR
始终创建日志文件目录。 默认情况下仅在未设置自定义日志文件位置时启用。
故障排除
如果你不能让初始化脚本工作,你应该尝试在 详细模式 下运行它们:
# sh -x /etc/init.d/celeryd start
这可以揭示有关为什么服务无法启动的提示。
如果工作程序以 “OK” 开始,但之后几乎立即退出并且日志文件中没有证据,则可能存在错误,但由于守护程序标准输出已经关闭,您将无法看到他们在任何地方。 对于这种情况,您可以使用 C_FAKEFORK
环境变量来跳过守护进程:
# C_FAKEFORK=1 sh -x /etc/init.d/celeryd start
现在您应该能够看到错误了。
通常,此类错误是由于读取或写入文件的权限不足,以及配置模块、用户模块、第三方库,甚至 Celery 本身的语法错误(如果您发现错误,您应该报告)。
用法 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 -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 以便 Systemd 确认该文件。 您还应该在每次修改它时运行该命令。 如果您希望 celery 服务在(重新)启动系统时自动启动,请使用 systemctl enable celery.service。
您可以选择为 celery 服务指定额外的依赖项:例如 如果您使用 RabbitMQ 作为代理,则可以在 [Unit]
systemd 部分 的 After=
和 Requires=
中指定 rabbitmq-server.service
。
要配置用户、组,chdir 更改设置:User
、Group
和 /etc/systemd/system/celery.service
中定义的 WorkingDirectory
。
您还可以使用 systemd-tmpfiles 来创建工作目录(用于日志和 pid)。
- 档案
- /etc/tmpfiles.d/celery.conf
d /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"
# 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"
服务文件: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 以便 Systemd 确认该文件。 您还应该在每次修改它时运行该命令。 如果您希望 celery beat 服务在(重新)启动系统时自动启动,请使用 systemctl enable celerybeat.service。
以超级用户权限(root)运行 worker
以超级用户权限运行 worker 是一种非常危险的做法。 应该总是有一个解决方法来避免以 root 身份运行。 Celery 可能会在用 pickle 序列化的消息中运行任意代码 - 这是危险的,尤其是在以 root 身份运行时。
默认情况下,Celery 不会以 root 身份运行 worker。 相关的错误消息可能在日志中不可见,但在使用 C_FAKEFORK
时可能会看到。
要强制 Celery 以 root 身份运行工作程序,请使用 C_FORCE_ROOT
。
在没有 C_FORCE_ROOT
的情况下以 root 身份运行时,worker 似乎以 “OK” 开始,但之后立即退出,没有明显错误。 在新的开发或生产环境中(不经意地)以 root 身份运行项目时,可能会出现此问题。