如何取消正在执行的Celery任务?

130 投票
9 回答
149510 浏览
提问于 2025-04-17 10:35

我一直在看文档和搜索,但似乎找不到明确的答案:

你能取消一个已经在执行的任务吗?(就是说这个任务已经开始了,花了一段时间,但在执行到一半的时候需要取消它)

我在文档中找到了这个内容,来自 Celery FAQ

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

但我不太清楚这是否会取消排队的任务,或者它会杀掉在工作进程中正在运行的任务。谢谢你能提供的任何信息!

9 个回答

38

@0x00mh的回答是对的,不过最近的celery 文档提到,使用terminate选项是“管理员的最后手段”,因为这样可能会不小心终止其他正在执行的任务。一个可能更好的解决办法是将terminate=Truesignal='SIGUSR1'结合使用(这样会在任务中引发SoftTimeLimitExceeded异常)。

61

在Celery 3.1版本中,取消任务的方式发生了变化。

根据Celery的常见问题解答,你应该使用result.revoke来取消任务:

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

或者如果你只有任务的ID,也可以这样做:

>>> from proj.celery import app
>>> app.control.revoke(task_id)
242

revoke 是用来取消任务执行的。如果一个任务被撤销了,工作者就会忽略这个任务,不再执行它。如果你没有使用持久化撤销,那么在工作者重启后,这个任务可能还是会被执行。

https://docs.celeryq.dev/en/stable/userguide/workers.html#worker-persistent-revokes

revoke 还有一个终止选项,默认是 False。如果你需要强制结束正在执行的任务,就需要把这个选项设置为 True

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)

https://docs.celeryq.dev/en/stable/userguide/workers.html#revoke-revoking-tasks

撰写回答