守护进程 — Python 文档

来自菜鸟教程
Celery/docs/latest/userguide/daemonizing
跳转至:导航、​搜索

守护进程

现在大多数 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 更改设置:UserGroup/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 身份运行项目时,可能会出现此问题。


:pypi:`主管`


launchd (macOS)