如何优雅地重新启动Celery工作进程?

52

当发布一个新构建以更新工作程序中的代码时,如何优雅地重启celery工作者?

编辑: 我的意图是做类似于这样的事情。

  • 工作者正在运行,可能正在将100 MB文件上传到S3
  • 新的构建出现
  • 工作者代码已更改
  • 构建脚本向工作者发送信号
  • 使用新代码启动新工作者
  • 接收到信号的工作者完成现有任务后退出。
9个回答

51

2
sudo ps auxww | grep celeryd | grep -v "grep" | awk '{print $2}' | sudo xargs kill -HUP 除了grep :-) - Quintin Par
5
你可以将 grep celeryd | grep -v "grep" 替换为 grep [c]eleryd。就是这样说的。 - chanux
4
看起来这不是一个优雅的重启,对吗?如文档所说:"除了停止然后启动工作进程进行重启外,您还可以使用HUP信号重启工作进程,但请注意,工作进程将负责自我重启,因此容易出现问题,不建议在生产环境中使用"。那么,在生产环境中重新加载Celery的最佳方法是什么,以避免故障呢? - mennanov
2
对于Celery Multi: "对于生产部署,您应该使用init脚本或其他进程监控系统"。至于HUP:"这容易出现问题,不建议在生产环境中使用"。 - webjunkie
1
Celery文档在这个问题上似乎存在自相矛盾的情况;这里说不要在生产中使用celery multi,但在守护进程部分,示例systemd配置文件使用了celery multi - GDorn

15

5
啊...它明确说了:“管理开发工人最简单的方法是使用celery multi。对于生产部署,您应该使用init脚本或其他进程监控系统。” 这个答案不适用于在生产环境中运行! - webjunkie
1
@Webjunkie,原帖并没有提到“在产品部署中”,所以如果原问题中没有提到这一点,不确定为什么您会对此进行负投票。 - zengr
3
他还没有表示他想要一个例如测试环境的解决方案。很多人不会花时间继续阅读并危险地使用他们认为正确的解决方案。因此,公平起见,应该提到缺点,而不是简单地从文档中复制粘贴内容,忽略注释并剥离其他建议。 - webjunkie

8

你可以做:

celery multi restart w1 -A your_project -l info  # restart workers

示例


6
如果您选择使用“kill”命令,可以使用pgrep命令进行救援:
kill -9 `pgrep -f celeryd`

请注意,这不是一个长时间运行的任务,如果它粗暴地终止我也不在意。只是在开发过程中重新加载新代码。如果更敏感的话,我会选择重新启动服务的方式。


4
pkill以更干净的方式执行此操作。 - orzel
我不知道那个。但是我仍然更喜欢事先看到将被杀死的进程列表:步骤1-调整您的pgrep,步骤2-通过将其提供给kill来武装它。 - JL Peyret

2

我已经使用自动化脚本反复测试了-HUP解决方案,但发现大约有5%的时间,工作进程在重新启动后停止接收新任务。

一种更可靠的解决方案是:

stop <celery_service>
start <celery_service>

我已经使用这种方法数百次了,没有出现任何问题。

从Python内部,您可以运行:

import subprocess
service_name = 'celery_service'
for command in ['stop', 'start']:
    subprocess.check_call(command + ' ' + service_name, shell=True)

2

2

5
这似乎是实验性的。这是一个旨在仅在开发过程中使用的实验性功能,不建议在生产环境中使用自动重载,因为Python重新加载模块的行为是未定义的。 - Quintin Par
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Thorin Schiffer
5
Celery 4 中似乎已经移除了自动重载选项。 - Mark Chackerian
1
自动重新加载已被弃用。 - Benny Chan

0
如果您正在使用docker/docker-compose,并将celery放入与Django容器不同的容器中,则可以使用以下命令:
docker-compose kill -s HUP celery

这里的 celery 是容器名称。工作进程将会优雅地重启,正在进行的任务不会被强制停止。

尝试过 pkill、kill、celery multi stop、celery multi restart、docker-compose restart 等方法,但都无法正常工作。要么容器被突然停止,要么代码没有重新加载。

我只想在生产服务器上手动重新加载我的代码,使用一行命令。不想与 daemonization 打交道。


-3

或许有些晚了,但我使用以下命令:

sudo systemctl stop celery

sudo systemctl start celery

sudo systemctl status celery


Unit celery.service could not be found. - egor83
大多数情况下,它不在systemctl下运行。 - TheNoobHunter66

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接