![](/style/images/good.png)
![](/style/images/bad.png)
正确使用Celery中的revoke来取消任务
source link: https://note.qidong.name/2021/09/celery-revoke/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
正确使用Celery中的revoke来取消任务
2021-09-04 17:17:55 +08 字数:1295 标签: Python
取消操作 ¶
Celery(本文基于5.1.2版本)有两种取消操作。
一是通过Control.revoke:
from celery.app.control.Control import revoke
ctrl = Control()
ctrl.revoke(task_id)
# Or terminate
ctrl.revoke(task_id, terminate=True)
ctrl.terminate(task_id)
当然,使用Control
最简单的办法是直接利用Celery的app
对象:
app.control.revoke(task_id)
二是通过AsyncResult.revoke:
from celery.result import AsyncResult
result = AsyncResult(task_id)
result.revoke()
# Or terminate
result.revoke(terminate=True)
二者基本是等价的,只是后者常用于复杂的操作场景,前者只是单纯地取消。
更多关于revoke
的内容,可以参考Revoking tasks。
以下基于AsyncResult.revoke进行介绍,省略写task_id
。
取消任务 ¶
并非所有任务状态,都可以取消。对于已经结束的任务,取消是无效操作。
可以被取消的只有:
- PENDING
- STARTED
- RETRY
取消PENDING ¶
这代表Task还在排队中,没有真正运行。只需要使用普通的取消即可。
result.revoke()
它的原理是,发广播通知所有worker,更新revoked列表。 当worker执行到revoked列表中的任务时,会直接跳过。
如果一个任务已经在运行,则以上操作无效。 因此,它只适用于取消未运行任务的场景,业务能容忍、或要求已运行任务自然地执行完毕。
取消STARTED ¶
如果一个任务已经在运行,通常处于STARTED状态。 取消这个任务,意味着中断这个运行过程。
result.revoke(terminate=True)
# Or with signal
import signal
result.revoke(terminate=True, signal=signal.SIGTERM)
要注意的是,terminate=True
意味着使用给定的signal,结束任务进程。
这里的signal,可以是signal模块的任意值。
默认的signal=None
,即等价于signal=signal.SIGTERM
。
在结束任务进程时,任务自己是不知道的。 因此,这只适用于粗暴终止的场景。
然而,SIGTERM
有时候并没有粗暴到底,会等一会儿,往往不是预期行为。
因此,如果要以终止的方式取消正在运行的任务,也可以使用SIGQUIT
。
利用SIGUSR1 ¶
尽管所有的signal都是可用的,但是有四个是Celery预留的特殊signal,详见Process Signals。
Signal
原文
备注
SIGTERM
Warm shutdown, wait for tasks to complete.
热停止,默认行为。
SIGQUIT
Cold shutdown, terminate ASAP
冷停止。
SIGUSR1
Dump traceback for all active threads.
发一个SoftTimeLimitExceeded异常。
SIGUSR2
Remote debug, see celery.contrib.rdb.
调试专用。
其中,SIGTERM
就是默认的Signal,很粗暴;SIGQUIT
则比它更粗暴。
至于不在上面的SIGKILL
、SIGINT
等,也不见得好多少。
如果想要让被终止的任务知道自己被终止,目前只能使用SIGUSR1
。
它会在任务正在执行的位置,抛出一个SoftTimeLimitExceeded。
因此,只需要在最外层用try ... except
捕获这个异常,就可以进行一些后处理。
但是,由于它的现象和任务超时是类似的,因此需要自行区分。
结论 ¶
对于只取消没有在运行的任务,只需要revoke
即可;
对于已经在运行的任务,则需要terminate=True
。
默认的signal=signal.SIGTERM
,有时结束得不够快,有时过于粗暴,缺少一些后处理。
因此,对不关心其运行情况的业务,也可考虑使用SIGQUIT
,甚至SIGKILL
。
对于需要做取消前做一些处理的,可以用SIGUSR1
。
Recommend
-
7
Celery+django如何显示任务的执行进度条 Celery单词中文的意思是“芹菜”,也不知道为什么人家喜欢给起个菜名,实际从功能上跟芹菜一点也扯不上关系,非得往上靠难道国外吃芹菜是在后面吃?大家都知道,如果我们在后端执行一个时间比较...
-
6
Python中使用Celery和Redis构建任务队列 | blutv您拥有的微服务越多,您就越需要在微服务或计划作业或后台任务之间进行异步消息传递。后台任...
-
11
Django动态添加定时任务之django-celery的使用 定时任务和周期任务在我们日常工作中应用广泛,例如定时发布、周期巡检等,通常我们会借助Linux下的Crontab来实现,但如何将这一功能搬进我们自研的运维系统呢?借助django-celery即可轻松完成...
-
2
Django配置Celery执行异步任务和定时任务 原生Celery,非djcelery模块,所有演示均基于Django2.0 celery是一个基于python开发的简单、灵活且可靠的分布式任务队列框架,支持使用任务队列的方式在分布式的...
-
8
Python Celery 任务执行有时成功有时失败(提示NotRegistered) 原创 tzchao 2022-03-31 11:...
-
6
celery分布式任务队列 Posted on...
-
1
Celery简介Celery 是一个异步任务队列/基于分布式消息传递的作业队列,Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行。通常使用它来实现异步任务(async task)和定时任务(crontab)
-
2
以前版本的 Celery 需要一个单独的库(django-celery)才能与 Django 一起工作, 但从 Celery 3.1 开始,情况便不再如此,我们可以直接通过 Celery 库来完成在 Django 中的任务。 安装 Redis 服务端...
-
7
排查 Celery 队列的任务问题 2023/9/26 0 Comments 198 Views 0 Times 近日使用 Celery 队列系统构造服务,遇到队列任务无法执行的问题,经过排查找到原因,记录一下,防止日后忘记。Celery 是一...
-
2
Celery多队列解决生产环境下的任务优先级问题 运维自动化系统需要处理大量的周期任务,例如上篇文章
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK