celery (二) task调用
调用 TASK
基础
task 的调用方式有三种:
- 类似普通函数的调用方式, 通过
__calling__调用 ,类似function() - 通过
apply_async()调用,能接受较多的参数 - 通过
delay()调用 ,是apply_async方法的快捷方法,可接受的参数较少
task.delay(arg1, arg2, kwarg1=1, kwarg2=2)
等同于
task.apply_async(args=[arg1, arg2], kwargs={'kwarg':1, 'kwarg2':2})
链接任务
通过链接的方式,可以在一个任务执行完毕之后,执行另一个任务。
add.apply_async(args=(2,2),link=add.s(6))
当第一个task完成之后,task的结果会作为第二个函数参数的的一部分传入第二个task。
上例第一个task结果为 4, 第二个task执行的是 \(4 + 6\) 。
如果第一个task失败,那么第一个task的 id 会被传入到第二个task中
@app.task
def error_handler(uuid):
result = AsyncResult(uuid)
exc = result.get(propagate=False)
print('Task {0} raised exception: {1!r}\n{2!r}'.format(
uuid, exc, result.traceback))
add.apply_async(args=(2), link=error_handler.s())
当然,两个是可以同时调用的
add.apply_async((2, 2), link=[add.s(16), error_handler21111.s()])
追踪状态
通过设置 on_message 回调函数,可以追踪 task 的状态变化
@app.task(bind=True)
def hello(self, a, b):
time.sleep(1)
self.update_state(state="PROGRESS", meta={'progress': 50})
time.sleep(1)
self.update_state(state="PROGRESS", meta={'progress': 90})
time.sleep(1)
return 'hello world: %i' % (a+b)
def on_raw_message(body):
print(body)
r = hello.apply_async()
print(r.get(on_message=on_raw_message, propagate=False))
{'task_id': '5660d3a3-92b8-40df-8ccc-33a5d1d680d7',
'result': {'progress': 50},
'children': [],
'status': 'PROGRESS',
'traceback': None}
{'task_id': '5660d3a3-92b8-40df-8ccc-33a5d1d680d7',
'result': {'progress': 90},
'children': [],
'status': 'PROGRESS',
'traceback': None}
{'task_id': '5660d3a3-92b8-40df-8ccc-33a5d1d680d7',
'result': 'hello world: 10',
'children': [],
'status': 'SUCCESS',
'traceback': None}
hello world: 10
ETA 和countdown 延迟执行
ETA(预估到达时间)配置一个具体的时间,是一个时间对象,这个时间是相关task的最早的执行时间(也就是说,该任务实际执行时间,可能晚于该时间)。countdown是ETA的快捷方式,countdown 是相对(当前)时间,单位是 秒。它表示该任务会在多少秒之后执行。
>>> from datetime import datetime, timedelta
>>> tomorrow = datetime.utcnow() + timedelta(days=1)
>>> add.apply_async((2, 2), eta=tomorrow) # 明天的当前时间执行
>>> result = add.apply_async((2, 2), countdown=3)
>>> result.get() # 3秒后执行
Expiration 任务保质期
通过配置 expiration 参数给task设置一个 过期时间,来保证task的时效性。当worker收到一个过期的任务之后,会标记该任务为 revoked(取消)状态。expiration 既可以是相对时间(单位:秒),也可以是绝对时间(时间对象)
add.apply_async((10, 10), expires=60)
>>> from datetime import datetime, timedelta
>>> add.apply_async((10, 10), kwargs,
... expires=datetime.now() + timedelta(days=1)
重试机制
celery会在连接失败的时候,自动尝试重新发送task。一般收到一个task,都会有一条 收到task的log信息。
通过设置 retry=False 来禁用自动重试。当然也可以通过配置其他参数来,配置celery自动重试的策略。
max_retries 最大重试次数
默认为3,如果设置为 None,表示一直重试。如果超过重试次数依旧失败,会引发一个导致重试失败的异常。
interval_start 重试等待时间
在多久之后开始重试,默认为 0 ,即可以重试。但是为 秒
interval_step 延迟重试 步长
连续重试的时候,每次重试之后,其延迟时间都会加上该参数的值。 默认是 0.2 ,单位为 秒
interval_max 重试延迟最大等待时间
每次重试之间,最大等待时间。 默认是 0.2 , 单位为 秒
add.apply_async((2, 2), retry=True, retry_policy={
'max_retries': 3,
'interval_start': 0,
'interval_step': 0.2,
'interval_max': 0.2,
})
# 最大重试次数为 3,第一次会在失败之后,立刻执行; 第二次会在第一次失败之后,等待0+0.2s执行;第三次会会 0+0.2(两次重试最大间隔为0.2,所以依旧是0.2,而不是0.4)。所以,三次重试一共耗时 0.2+0.2 = 0.4s
连接失败,或者是无法建立连接的时候,celery会引发OperationalError 异常。但是如果配置了自动重试,那么该异常只会在重试次数耗尽之后,依旧无法建立连接的时候,才引发。
>>> from celery.utils.log import get_logger
>>> logger = get_logger(__name__)
>>> try:
... add.delay(2, 2)
... except add.OperationalError as exc:
... logger.exception('Sending task raised: %r', exc)
序列化
在celery的客户端和worker之间发送消息的时候,需要对消息进行序列化。默认的序列化方式是 JSON,可以通过在 setting 中配置 task_serializer 来更改默认的序列化方式,当然可以对每个task分别设置序列化方式。支持的序列化方式有:JSON YAML PICKLE msgpck
压缩
celery 同样可以在传送消息的时候,对其进行压缩。压缩方式有:gzip 和bzip2 。
有如下三种方式来配置压缩属性,按优先级分别为:
- compression 调用task时,配置该参数
- Task.compression 属性。配置自定义 Task类的属性
- task_compression 在配置文件中配置 该属性
celery (二) task调用的更多相关文章
- 异步任务利器Celery(二)在django项目中使用Celery
Celery 4.0支持django1.8及以上的版本,低于1.8的项目使用Celery 3.1. 一个django项目的组织如下: - proj/ - manage.py - proj/ - __i ...
- 分布式任务队列 Celery —— 深入 Task
目录 目录 前文列表 前言 Task 的实例化 任务的名字 任务的绑定 任务的重试 任务的请求上下文 任务的继承 前文列表 分布式任务队列 Celery 分布式任务队列 Celery -- 详解工作流 ...
- [源码解析] 并行分布式任务队列 Celery 之 Task是什么
[源码解析] 并行分布式任务队列 Celery 之 Task是什么 目录 [源码解析] 并行分布式任务队列 Celery 之 Task是什么 0x00 摘要 0x01 思考出发点 0x02 示例代码 ...
- php分页类的二种调用方法(转载)
php分页类的二种调用方法 原文地址:http://www.xfcodes.com/php/fenye/25584.htm 导读:php分页类的二种调用用法,ajax调用php分页类,非ajax方式调 ...
- Spring ApplicationListener使用方法及二次调用问题解决
使用场景 在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载.初始化缓存.特定任务的注册等等.这个时候我们就可以使用Spring提供的ApplicationListener来 ...
- Veins(车载通信仿真框架)入门教程(二)——调用第三方库
Veins(车载通信仿真框架)入门教程(二)——调用第三方库 在借助Veins进行自己的研究时我们经常需要实现一些比较复杂的功能,有时就需要借助第三方库的帮助. 博主的研究需要使用神经网络,但是自己编 ...
- 基于Django+celery二次开发动态配置定时任务 ( 一 )
需求: 前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统.监控,于是乎开发.测试.产品.运营.业务部.财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们.刚开始一天一个还 ...
- 结合Django+celery二次开发定时周期任务
需求: 前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统.监控,于是乎开发.测试.产品.运营.业务部.财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们.刚开始一天一个还 ...
- [python基础] celery beat/task/flower解析
一.Celery 介绍 Celery 是一个强大的分布式任务队列,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务( async task )和定时任务( ...
随机推荐
- 鏈接Redis報錯`AUTH` failed: ERR Client sent AUTH, but no password is set [tcp://127.0.0.1:6379]
問題 鏈接Redis報錯`AUTH` failed: ERR Client sent AUTH, but no password is set [tcp://127.0.0.1:6379] 解決 啟動 ...
- H5外包 微信小程序外包 小程序外包 就找北京动点开发团队
长年承接微信小程序.微信公众号开发 全职的H5开发团队,开发过几十款微信小程序公众号案例 欢迎来电咨询 QQ:372900288 微信:liuxiang0884 TEL:13911652504
- 图像频谱图画图——matlab
I =imread('C:\Users\wangd\Desktop\in000155.jpg'); %读入原图像文件 I1 = rgb2gray(I); subplot(,,);imshow(I1); ...
- CentOS 7.x 如何关闭 numa
CentOS7.x中发现 numactl --interleave=all 执行失败. CentOS7.x中可以通过下面的方式关闭 numa: 1. 编辑 /etc/default/grub 文件,如 ...
- django orm 管理器 objects
给某张表的管理器重命名 class User(models.Model): name = models.CharField(max_length=100) people = models.Manage ...
- 20175236 JAVA MyCP(课下作业)
具体描述: 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容 ...
- udev磁盘绑定
udev磁盘绑定 [grid@db-rac02 ~]$ cat 99-asm-multipath.rules KERNEL=="sd*",SUBSYSTEM=="bloc ...
- Centos7之系统优化
优化条目: 修改ip地址.网关.主机名.DNS等 关闭selinux,清空iptables 添加普通用户并进行sudo授权管理 更新yum源及必要软件安装 定时自动更新服务器时间 精简开机自启动服务 ...
- 移植QT库的问题:QT_INSTALL/include/QtCore/qatomic_arm.h:131: Error: no such instruction: `swpb %al,
解决办法:错误信息说明编译器未识别swpb汇编操作,指令集有问题.把配置命令改成: ./configure -embedded armv7 -prefix /home/thwijeth/Softwar ...
- nginx+多个tomcat
学习nginx的时候遇到的问题:nginx怎么部署两台tomcat? upstream 在网上找的资源,我在nginx配置文件(nginx.conf)中添加了两个server.结果只显示第一个se ...