有没有办法非暴力地停止芹菜工人的特定任务?
Posted
技术标签:
【中文标题】有没有办法非暴力地停止芹菜工人的特定任务?【英文标题】:Is there any way to non-violently stop particular task of celery worker? 【发布时间】:2016-09-14 20:16:38 【问题描述】:正如 Celery documentation 所说,已经执行的任务不会通过调用 .revoke()
中止,除非设置了 terminate=True
。但不建议这样做,因为它会杀死工人本身,这可能已经开始了另一项任务。这是否意味着没有可靠、稳定的方法来做到这一点?
编辑:celery.contrib.abortable
不适合我,因为正如文档所述,它仅适用于数据库后端。
【问题讨论】:
这取决于您尝试终止的任务(网络、文件、数据库操作等),请看一下这个示例:***.com/questions/37039941/celery-python-revoke 在我的情况下,我的主要任务调用子进程除非我发送 SIGKILL 信号,否则不会终止。 Stopping celery task gracefully的可能重复 【参考方案1】:一个正在运行的任务是worker的一个正在运行的子进程(当使用prefork时),这意味着中止一个任务的唯一方法是杀死正在运行它的子进程。
您可以尝试自己的撤销事件处理实现,试图找出子进程 ID 并只杀死那个,但老实说,不知道是否值得以及它是否真的可以工作。
我认为简短的回答是你不能。
无论如何有时需要杀死工人,特别是在项目的初始阶段,您仍然需要正确确定资源的尺寸,只需确保您在某处记录正在运行的任务,以便您可以重新安排它们或只使用CELERY_ACKS_LATE
【讨论】:
“无论如何杀死工人并不罕见” 什么通常条件会保证强制终止生产系统中的工人?我已经使用 Celery 几年了,唯一一次强制终止工人是在必须关闭站点进行维护时。 取决于用例,我以前在一个大型社区网站工作,我们在高峰期遇到了一些问题。工人们占用了大量的记忆和冻结。当然,这是因为我们没想到负载和工人的尺寸不正确。但我可以告诉你,一年内发生了几次,不考虑其他因素导致的机器完全崩溃。 我在 Louis 评论后通过回答澄清了。【参考方案2】:您可以发送 HUP 信号而不是 TERM,它可以优雅地重新启动子进程而不会杀死工作人员。
In [80]: import signal
In [81]: x = add.delay(1, 2)
In [82]: x.revoke(terminate=True, signal=signal.SIGHUP)
【讨论】:
"除了先停止再启动worker重启,也可以使用HUP信号重启worker,但是注意worker会自己负责重启,这样容易出问题,不会推荐在生产中”Source @Louis 如果你有一个并发为 4 的 worker,它有 4 个进程一次运行 4 个任务。现在重新启动它只是撤销任务是一个坏主意,因为它可能会中断其他进程。上面的命令只会重启正在运行该任务的单个进程。以上是关于有没有办法非暴力地停止芹菜工人的特定任务?的主要内容,如果未能解决你的问题,请参考以下文章