用Celery取消已执行的任务?

dco*_*296 84 python django message-passing celery

我一直在阅读文档和搜索,但似乎无法找到一个直接的答案:

你能取消已经执行的任务吗?(在任务开始时,需要一段时间,需要取消一半)

我在Celery FAQ的文档中找到了这个

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()
Run Code Online (Sandbox Code Playgroud)

但我不清楚这是否会取消排队的任务,或者它是否会杀死一个正在运行的进程.感谢您可以放下任何光线!

mhe*_*her 157

revoke取消任务执行.如果任务被撤销,则工作人员会忽略该任务而不执行该任务.如果不使用持久性撤销,则可以在工作人员重新启动后执行任务.

http://docs.celeryproject.org/en/latest/userguide/workers.html#worker-persistent-revokes

revoke有一个terminate选项,默认为False.如果需要终止执行任务,则需要将terminate设置为True.

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)
Run Code Online (Sandbox Code Playgroud)

http://docs.celeryproject.org/en/latest/userguide/workers.html#revoke-revoking-tasks

  • 此外,根据最近的Celery文档,使用terminate选项是"管理员的最后手段".您可能会终止最近在该工作者上启动的另一个任务. (7认同)
  • result.revoke(terminate = True)应该执行与revoke相同的操作(task_id,terminate = True) (3认同)
  • 这正是我要的解释,谢谢! (2认同)
  • 这在分布式环境中有效吗?我的意思是,如果我有工作人员在多台机器上执行任务。celery 是否跟踪任务正在哪台机器上执行? (2认同)
  • 它不起作用,```>>> from proj.celery import app <br> >>> app.control.revoke(task_id) ``` 这仅起作用 (2认同)

Roc*_*ite 32

在Celery 3.1中,撤销任务API已更改.

根据Celery FAQ,你应该使用result.revoke:

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()
Run Code Online (Sandbox Code Playgroud)

或者如果您只有任务ID:

>>> from proj.celery import app
>>> app.control.revoke(task_id)
Run Code Online (Sandbox Code Playgroud)


kou*_*ouk 22

@ 0x00mh的答案是正确的,但是最近的芹菜文档说使用该terminate选项是" 管理员的最后手段 ",因为你可能会意外地终止同时开始执行的另一个任务.可能是一个更好的解决方案结合terminate=True使用signal='SIGUSR1'(这将导致SoftTimeLimitExceeded例外任务待提高).

  • 这个解决方案对我来说非常有效。当我在任务中提出“ SoftTimeLimitExceeded”时,将调用我的自定义清除逻辑(通过“ try” /“ except” /“ finally”实现)。在我看来,这比“ AbortableTask”提供的功能要好得多(http://docs.celeryproject.org/en/latest/reference/celery.contrib.abortable.html)。对于后者,您需要数据库结果后端_and_,您必须手动并反复检查正在进行的任务的状态,以查看其是否已中止。 (2认同)
  • 据我所知,如果该进程还有其他任务要执行,无论如何它都会停止,这会更好吗,只会抛出不同的异常。 (2认同)

小智 8

根据 5.2.3 文档,可以运行以下命令:

    celery.control.revoke(task_id, terminate=True, signal='SIGKILL')
Run Code Online (Sandbox Code Playgroud)

在哪里 celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])

链接到文档:https://docs.celeryq.dev/en/stable/reference/celery.app.control.html ?highlight=revoke#celery.app.control.Control.revoke


小智 6

您可以使用代理和后端定义 celery 应用程序,例如:

from celery import Celery
celeryapp = Celery('app', broker=redis_uri, backend=redis_uri)
Run Code Online (Sandbox Code Playgroud)

当您运行发送任务时,它会返回任务的唯一 ID:

task_id = celeryapp.send_task('run.send_email', queue = "demo")
Run Code Online (Sandbox Code Playgroud)

要撤销任务,您需要 celery 应用程序和任务 ID:

celeryapp.control.revoke(task_id, terminate=True)
Run Code Online (Sandbox Code Playgroud)


小智 5

另外,不尽如人意的是,还有另一种方式(abort task)来停止任务,但也有很多不可靠的地方,更多详情参见: http ://docs.celeryproject.org/en/latest/reference/celery.contrib.abortable .html