管理 Celery worker 的启动、排空与服务化

依据 Ask Solem 与 Celery 文档贡献者的 Workers Guide、Daemonization、Security 合并翻译整理。2026-10-05 核对,原站 stable 为 Celery 5.6.3;本文与原创配图依 CC BY-SA 4.0 发布。

Celery 停机状态:TERM 或首次 Ctrl+C 进入 warm 等待任务,启用的 soft 阶段提供限时窗口,cold 取消任务,hard 强制终止;服务管理器超时也可能提前截断。
图:Celery 关闭阶段的作用与风险;箭头表示本文阅读顺序,具体信号可直接触发 cold。未完纪原创,CC BY-SA 4.0。

停止一个 Celery worker,并不只是结束 Python 进程。它还涉及正在执行的任务、已预取但未执行的消息、ETA/countdown 任务、broker 的确认状态,以及服务管理器准备何时强制收尾。只有把这些状态放在一起,才知道一次重启是否真的保留了工作的连续性。本文把 worker 生命周期、守护进程配置和安全边界合在同一条操作思路中。

一、前台启动与实例命名

celery -A proj worker -l INFO
celery worker --help

proj 是示例应用,必须换成自己的 Celery app。先以前台方式确认应用导入、依赖、broker 连接和日志正常,再交给服务管理器。原文允许同机启动多个 worker,但每个实例应有独立节点名:

celery -A proj worker --loglevel=INFO --concurrency=10 -n worker1@%h
celery -A proj worker --loglevel=INFO --concurrency=10 -n worker2@%h

在 --hostname 中,%h 展开为包含域名的主机名,%n 为主机名部分,%d 为域名。例如 george.example.com 对应 worker1@george.example.com、worker1@george 与 worker1@example.com。Supervisor 配置里的百分号需要写成 %%h。并发数 10 是原文例子,不是默认推荐值。

--logfile、--pidfile 和 --statedb 也支持变量。完整节点名是 %p,prefork 子进程索引是 %i,带分隔符的索引是 %I。例如 %n%I.log 可以形成主进程日志和独立子进程日志;这里索引不是 PID,也不是进程累计创建数量。为每个实例分开 PID、日志和状态文件,避免互相覆盖。

二、理解四种关闭阶段

正常停止优先使用 TERM,让 worker 完成正在执行的任务。原文区分 Warm、Soft、Cold、Hard 四个阶段;其中 Soft 和 Hard 的相关行为在 5.5 加入。反复按 Ctrl+C 会推进阶段,不是无害的“再提醒一次”。

阶段 触发与行为 需要核对
Warm TERM 或首次 INT;等当前任务完成,调用 WorkController.stop() 期间额外 TERM 被忽略,下一次 INT 会推进关闭
Soft cold 前的限时 warm;允许任务继续 worker_soft_shutdown_timeout 秒 默认关闭,超时后取消任务;不是所有 warm 停机都自动有超时
Cold QUIT;停止当前任务并终止,调用 terminate() REMAP_SIGTERM=SIGQUIT 会让 TERM 也变成 cold
Hard 连续 INT 推到立即终止;主进程抛出 WorkerTerminate 主要供本地或调试使用,不保证消息恢复

Celery 5.6 修正了 prefork 池 warm shutdown 期间的 broker 心跳行为:旧版本在此期间不发心跳,broker 可能断开连接,影响任务完成;5.6 在该池的 warm 阶段保持心跳。这个改动不能被推广成所有池、所有任务和网络故障都能安全排空的保证。

Soft shutdown 必须把 worker_soft_shutdown_timeout 设为正数才能启用。如果没有正在执行的任务,默认会跳过 soft;但 worker 此时可能仍持有预留的 ETA 任务。原文因此建议这类场景启用 worker_enable_soft_shutdown_on_idle,并针对实际 broker 和任务行为实验时限。

# 配置示意;10 秒不是通用排空时限
worker_soft_shutdown_timeout = 10.0
worker_enable_soft_shutdown_on_idle = True

在 soft 阶段再收到 QUIT,当前任务会被取消,但 worker 仍等待既定时限,以便更平缓地完成 cold 收尾。继续发送信号可能进入下一阶段。原文日志中的 Restoring 1 unacknowledged message(s) 不代表消息已经可靠放回 broker;hard shutdown 后尤其不能仅凭这行日志判断恢复成功。

危险示例处理:原页给出全局匹配进程的 pkill -9 -f 和管道式批量强杀命令。本文只在原文对照中保留它们,不作为可执行建议:它们可能误杀同机其他实例,而且 KILL 不允许进程自行清理。原文注明 Linux 上从 5.2 起借助 PR_SET_PDEATHSIG 改善子进程终止处理;这也不能恢复被打断的业务事务。acks_late 只影响消息确认策略,不能单独证明任务会重新执行或只执行一次。

三、停止后重启,比让 worker 自行重启更清楚

官方建议的重启方式是先发 TERM,再启动新实例。开发环境可用 celery multi;生产环境宜由进程管理器托管。下面根据 Daemonization 章节整理,目录需要预先存在且仅授予运行账户所需权限:

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"

编辑修订:原页 restart 的 --pidfile 参数缺少闭合双引号,上面已经补齐。启动、停止和重启必须指向同一实例的同一组文件。原文也提到 HUP 自重启,但它依赖无控制终端的守护模式,容易出问题,不推荐生产使用;macOS 上此能力因平台限制被禁用。

四、broker 断线后的重连不等于任务恢复

检查 broker_connection_retry_on_startup 和 broker_connection_retry,分别理解启动连接与后续重连的策略。原文从 5.1 起提供 worker_cancel_long_running_tasks_on_connection_loss:设为 True 时,连接丢失也可能取消正在执行的长任务。不要一边期待长任务继续,一边忽略这个开关。

从 5.3 起,Celery 会考虑断线前已获取的任务:重连时,将预取计数按“仍在运行的任务数 × worker_prefetch_multiplier”降低;随着这些任务完成,再逐步恢复到最大值。worker_enable_prefetch_count_reduction 默认启用,可显式关闭。它缓和重复预取带来的负载问题,却不是业务副作用的去重机制。

五、把停止语义落实到 systemd

Daemonization 原页同时介绍通用 init.d 脚本和 systemd。现代 Linux 可用 systemctl --version 确认服务管理器;原文中的版本输出只是示例。systemd 的 SysV 兼容层可能运行旧 init 脚本,但新部署应按本机管理方式选一种明确方案。

原页 systemd worker 示例是 Type=forking,用 celery multi start/stopwait/restart,通过 /etc/conf.d/celery 提供 app、节点名、PID/日志路径等变量;工作目录、运行用户和组由 unit 控制。更改 unit 后需要 daemon-reload;是否 enable 开机启动应按实际部署决定。若依赖本机 RabbitMQ,还可按部署关系设置 After 与 Requires,不能以一个 network.target 就认定远端 broker 已可用。

下面是编辑新增的单 worker 前台托管方案,为了展示服务管理器与 warm shutdown 的关系,未照抄原页 forking+multi。路径、账户、并发和 900 秒停止窗口都必须按自己的应用确认;它没有经过部署测试。

[Unit]
Description=Example Celery worker
After=network.target

[Service]
Type=simple
User=celery
Group=celery
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/.venv/bin/celery -A proj worker -l INFO -n worker1@%%h
KillSignal=SIGTERM
KillMode=mixed
TimeoutStopSec=900
Restart=on-failure

[Install]
WantedBy=multi-user.target

这个方案由 systemd 跟踪前台主进程,日志进入 journal,因此省去手工 PID 文件。%%h 用来在 unit 命令中保留字面百分号,交给 Celery 展开。KillMode=mixed 的初始信号针对主进程,但停止超时后仍可能终止整个进程组;900 秒不是任何系统的安全保证。必须把最长任务、soft/cold 收尾、broker 等待以及运维所容许的最长停机时间放在同一预算里。

若沿用原页的文件日志与多节点方案,先创建 PID/日志目录并赋给专用账户;原文给出的 tmpfiles 项为 /run/celery、/var/log/celery,权限 0755,属主属组 celery。prefork 日志用 %n%I.log,避免多个子进程争用同一文件。配置文件包含 shell 解释内容时,应限制谁可以写入,不能让非可信输入变成启动命令。

Celery Beat 是另一种服务角色。原页提供 Type=simple 的 beat unit,并单独设置 CELERYBEAT_PID_FILE、CELERYBEAT_LOG_FILE 或 schedule 数据路径。不要把 worker 成功启动等同于周期任务调度器已经运行;同一调度计划重复启动多个调度器也需要额外协调。

六、旧 init 脚本与启动故障如何排查

通用 init.d 脚本位于 Celery 仓库的 extra/generic-init.d/。worker 常读 /etc/default/celeryd,beat 可读 /etc/default/celerybeat;这些是 shell 配置,真正需要传给子进程的环境变量应 export。原页要求 init 脚本由 root 使用、配置文件归 root 所有,但 worker 本身应切换到非特权账户。

配置组 作用
CELERY_BIN / CELERY_APP 命令路径与 app;可用虚拟环境中的 celery 或 python -m celery
CELERYD_NODES / CELERYD_OPTS 节点列表与 worker 参数;multi 支持按节点定制
CELERYD_CHDIR / CELERYD_USER / CELERYD_GROUP 工作目录及运行身份
CELERYD_PID_FILE / CELERYD_LOG_FILE / CELERYD_LOG_LEVEL 实例文件及日志等级
CELERY_CREATE_DIRS / CELERY_CREATE_RUNDIR / CELERY_CREATE_LOGDIR 是否创建运行和日志目录;自定义路径尤其要核对
CELERYBEAT_OPTS / CELERYBEAT_* 文件及账户项 beat 对应的参数、状态文件、日志与身份

原页 --time-limit=300 限制单个任务运行时间,不是“给停机 300 秒”。Django 项目还需正确设置 DJANGO_SETTINGS_MODULE,并确保工作目录和 app 模块能被导入。CELERYD_SU_ARGS="-l" 会使用登录 shell 继承环境,原文只建议在确有必要时使用。

如果显示 OK 后立即退出,先检查前台运行和真实日志;在受控环境中,可通过 init 脚本的 sh -x 与 C_FAKEFORK=1 查看守护化前的错误。调试输出可能包含配置值,分享前要去除敏感信息。常见问题包括文件权限和配置/模块语法错误,不能因为看不到错误就开启 C_FORCE_ROOT 绕过限制。原文还给出 Supervisor 与 macOS launchd 的仓库示例链接,应按相应平台单独核对。

七、从 broker、客户端到 worker 限制信任

安全章要求把 Celery 当作需要防护的组件。broker 应限制网络来源,配合账户与队列等细粒度权限;防火墙可能被误改或短暂关闭,因此还要监测配置。后端支持时,用 broker_use_ssl 配置传输加密与认证。客户端是任何向 broker 发消息的程序,例如 Web 服务;若客户端允许任意人发送任意任务,broker 自身配置再严也不够。原页 Client 小节仍有缺文标记,本文不把它描述成完整的客户端安全方案。

任务通常拥有 worker 的文件、设备与网络权限。prefork 子进程也会继承 fork 时复制的内存,并可能接触同一子进程先前任务留下的内容。原文讨论 fork+exec、chroot/jail/sandbox/虚拟机及出站防火墙等隔离手段;这些都需要按实际威胁模型配置,不能把一个“非 root”开关当作完整隔离。

JSON 从 Celery 4.0 起是默认序列化格式。pickle 可以表示复杂 Python 对象,也因此不适合不可信或未认证的客户端。可明确限制接受的内容:

accept_content = ['json']
# 等价的内容类型写法:['application/json']

此选项从 3.0.18 起支持,更早版本会忽略。即使采用 JSON,任务名、参数和客户端权限仍需验证;“不是 pickle”并不代表可以接受任意人调用任意任务。

八、签名验证发送者,但不加密消息

Celery 的 auth serializer 使用公钥密码学:发送端用私钥签名,worker 用证书验证来源。需要设置 task_serializer='auth'、accept_content=['auth'];事件若也要签名,可设 event_serializer='auth'。此外要指定私钥、证书、可信证书集合、摘要算法,必要时提供加密私钥口令,最后调用 app.setup_security()。

# 根据原文补齐语法;路径、信任集合和 app 配置必须另行设计
from celery import Celery

app = Celery()
app.conf.update(
    security_key='/etc/celery/private/signer.key',
    security_certificate='/etc/celery/certs/signer.pem',
    security_cert_store='/etc/celery/trusted-senders/*.pem',
    security_digest='sha256',
    task_serializer='auth',
    event_serializer='auth',
    accept_content=['auth'],
)
app.setup_security()

编辑修订:原文前两个键值后缺逗号,此处已补齐并显式导入 Celery;还把宽泛的 /etc/ssl/certs/*.pem 改成专用受信发送者目录,避免把系统证书集合未经审查地当作消息发送者信任列表。这只是静态配置示意,不含真实私钥,也没有配置 broker、证书发放、轮换与吊销流程。auth 不加密消息内容,保密性仍需额外处理。

入侵检测同样重要。原文建议受限的集中日志以降低攻击者篡改本机日志的机会,并提到 Tripwire、OSSEC、Samhain、AIDE 等文件完整性工具与 ZFS 校验。哈希告警需要可信基线,完整性校验也不能替代访问控制;原页关于日志传输的玩笑性建议不作为本文部署步骤。

九、原文后半部分的管理工具与边界

Workers Guide 还有远程控制、限时、限速、队列与自定义命令。以下按与运维相关的要点整理;具体执行前应确认池类型与 broker 支持,别把控制广播发到不相关实例。

  • 并发:默认使用 multiprocessing/prefork,可通过 --concurrency 调整。进程越多并不总越快;单大实例和多个小实例的差异需按负载测量。
  • 远控:原文列出的 broker 是 RabbitMQ/AMQP 与 Redis;命令可以广播,也可用 destination 指定 worker。默认回复超时一秒,没有回复不代表实例死亡。solo 池正执行任务时可能阻塞控制命令。
  • 撤销:revoke 通常只让尚未执行的任务被跳过;terminate 会终止执行任务的进程,信号送达时进程可能已经接手别的任务,原文明确不可把它当作程序化取消机制。5.6 会立即把撤销状态写入结果后端。
  • 撤销状态:任务 ID 列表默认在内存,全部 worker 重启会丢失,需 --statedb 持久化并按实例分文件。原文默认最多保留 50000 个撤销 ID,超过限制后的有效期默认为 10800 秒;成功任务缓存相关默认值为 1000 和 10800 秒。按 stamped headers 的撤销映射不跨重启持久化,启用 terminate 时遍历高并发任务也有成本。
  • 任务限时:soft time limit 允许捕获 SoftTimeLimitExceeded 清理;hard time limit 终止并替换执行进程。它们和 worker 的 soft shutdown 是不同概念。不支持 SIGUSR1 的平台有限制,gevent 不实现 soft limit,阻塞任务也可能无法按 hard limit 收尾。运行时更改只影响之后开始的任务。
  • 限速与回收:rate_limit 可指定目标实例,禁用限速的 worker 不受影响;prefork 的 --max-tasks-per-child 与 --max-memory-per-child 用于按任务数或常驻内存回收子进程,不能修复业务本身的泄漏。
  • 自动扩缩:--autoscale=10,3 表示上限 10、下限 3;原文支持 prefork/gevent,也可以继承 Autoscaler 按负载或可用内存定制。
  • 队列:-Q foo,bar 选择启动时消费的队列;未定义队列是否自动创建受 task_create_missing_queues 控制。add_consumer 是幂等添加消费,cancel_consumer 停止消费,active_queues 用于检查;停止消费不等于所有已预留任务消失。
  • 状态检查:registered 列出任务注册,active 是执行中,reserved 是已接收等待执行,scheduled 是 ETA/countdown,不能把 scheduled 当作周期任务表。stats、ping 和事件开关用于观测,USR1 可转储线程 traceback,USR2 关联远程调试,均要控制访问。
  • 扩展:inspect_command 用于只读查询,control_command 可以改变状态;原文通过增加预取数与读取当前预取数说明两者区别。模块须被 worker 导入,重启后命令才注册。自定义入口应验证参数,不给不可信调用者开放管理权限。

来源、改动和验证边界

本文围绕“启动—停止—重连—托管—信任”合并三章,压缩重复的控制台输出与平台重复配置,保留版本、信号、消息恢复和权限边界。所有命令和配置只做静态核对,没有运行 worker、连接 broker、终止进程或部署签名方案。任务成功必须结合业务结果、broker/结果后端和幂等设计判断,不能从一行关闭日志推出。

版权声明:Celery User Manual,Copyright © 2009–2016 Ask Solem;原文和本翻译整理依 Creative Commons Attribution-ShareAlike 4.0 International 使用。翻译、合并、代码标点修复、单 worker systemd 示例以及安全说明为本文改动。Celery 软件本身另依 BSD 3-Clause 发布。来源版权说明见 Celery docs/copyright.rst。静态审核没有发现更多问题不等于代码不存在漏洞。

原文生命周期、守护化与签名配置对照

以下按原文顺序保留原始配置、日志和命令,以便核对主文修订;没有执行。原文的全局pkill/kill -9可能误杀其他实例、丢失任务;仅供审查其风险,不作为停止建议。原restart引号及签名配置逗号缺陷仍以正文修正版为准。模板包含root控制的shell配置和服务操作,不能用不可信值拼入;systemd默认停止窗口也不能保证任务排空。

原文片段 1

$ celery -A proj worker -l INFO

原文片段 2

$ celery worker --help

原文片段 3

$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker1@%h
$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker2@%h
$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker3@%h

原文片段 4

$ pkill -9 -f 'celery worker'

原文片段 5

$ ps auxww | awk '/celery worker/ {print $2}' | xargs kill -9

原文片段 6

[INFO/MainProcess] Task myapp.long_running_task[6f748357-b2c7-456a-95de-f05c00504042] received
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 1/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 2/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 3/2000s
^C
worker: Hitting Ctrl+C again will initiate cold shutdown, terminating all running tasks!
worker: Warm shutdown (MainProcess)
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 4/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 5/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 6/2000s
^C
worker: Hitting Ctrl+C again will terminate all running tasks!
[WARNING/MainProcess] Initiating Soft Shutdown, terminating in 3 seconds
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 7/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 8/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 9/2000s
[WARNING/MainProcess] Restoring 1 unacknowledged message(s)

原文片段 7

[INFO/MainProcess] Task myapp.long_running_task[7235ac16-543d-4fd5-a9e1-2d2bb8ab630a] received
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 1/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 2/2000s
^C
worker: Hitting Ctrl+C again will initiate cold shutdown, terminating all running tasks!
worker: Warm shutdown (MainProcess)
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 3/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 4/2000s
^C
worker: Hitting Ctrl+C again will terminate all running tasks!
[WARNING/MainProcess] Initiating Soft Shutdown, terminating in 10 seconds
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 5/2000s
[WARNING/ForkPoolWorker-8] long_running_task is running, sleeping 6/2000s
^C
Waiting gracefully for cold shutdown to complete...
worker: Cold shutdown (MainProcess)
^C[WARNING/MainProcess] Restoring 1 unacknowledged message(s)

原文片段 8

$ celery multi start 1 -A proj -l INFO -c4 --pidfile=/var/run/celery/%n.pid
$ celery multi restart 1 --pidfile=/var/run/celery/%n.pid

原文片段 9

$ kill -HUP $pid

原文片段 10

* Init-script: `celeryd` L6: 
  * Example configuration L8: 
  * Using a login shell L10: 
  * Example Django configuration L12: 
  * Available options L14: 
* Init-script: `celerybeat` L16: 
  * Example configuration L18: 
  * Example Django configuration L20: 
  * Available options L22: 
* Service file: celerybeat.service L31: 

原文片段 11

$ systemctl --version
systemd 249 (v249.9-1.fc35)
+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified

原文片段 12

$ 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"

原文片段 13

# 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

原文片段 14

CELERYD_SU_ARGS="-l"

原文片段 15

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

原文片段 16

export DJANGO_SETTINGS_MODULE="settings"
CELERYD_CHDIR="/opt/MyProject"

原文片段 17

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

原文片段 18

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

原文片段 19

[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

原文片段 20

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

原文片段 21

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

原文片段 22

[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

原文片段 23

* Broker L9: 
* Client L11: 
* Worker L13: 

原文片段 24

* Logs L21: 
* Tripwire L23: ## Introduction ¶ L24: 

原文片段 25

accept_content = ['json']

原文片段 26

accept_content = ['application/json']

原文片段 27

app = Celery()
app.conf.update(
    security_key='/etc/ssl/private/worker.key'
    security_certificate='/etc/ssl/certs/worker.pem'
    security_cert_store='/etc/ssl/certs/*.pem',
    security_digest='sha256',
    task_serializer='auth',
    event_serializer='auth',
    accept_content=['auth']
)
app.setup_security()

原init默认项补充:worker的PID路径为/var/run/celery/%n.pid、日志为/var/log/celery/%n%I.log,beat对应默认/var/run/celeryd.pid与/var/log/celeryd.log;默认日志等级INFO,运行用户/组默认当前身份。未配置chdir时保持当前目录。CREATE_DIRS/RUNDIR/LOGDIR默认仅在未自定义相应文件位置时创建,不能假定自定义父目录会出现。

签名使用cryptography库;源文优先采用正式CA签发证书,也允许自签。信任配置仍必须明确指定受信发送者,文件路径建议绝对路径;加密私钥可用security_key_password。集中日志可通过Python logging的syslog支持实现;原文关于UDP与剪断发送线的句子是玩笑,不是可实施安全方案。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容