依据 Ask Solem 与 Celery 文档贡献者的 Workers Guide、Daemonization、Security 合并翻译整理。2026-10-05 核对,原站 stable 为 Celery 5.6.3;本文与原创配图依 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与剪断发送线的句子是玩笑,不是可实施安全方案。












暂无评论内容