目录 一、Celery 对象解析二、创建异步任务的方法 task三、调用异步任务的三种方法四、获取任务结果和状态五、Celery 使用案例
一、Celery 对象解析
我们先来看一下 Celery 的初始化方法:
class Celery(object): def __init__(self, main=None, loader=None, backend=None, amqp=None, events=None, log=None, control=None, set_as_current=True, accept_magic_kwargs=False, tasks=None, broker=None, include=None, changes=None, config_source=None, fixups=None, task_cls=None, autofinalize=True, **kwargs):常用的需要配置的参数:
这些参数都是 celery 实例化的配置,我们也可以不写,可以使用config_from_object方法加载配置;
二、创建异步任务的方法 task
任何被 task 修饰的方法都会被创建一个 Task 对象,变成一个可序列化并发送到远程服务器的任务;它有多种修饰方式:
方式一:使用默认的参数
@celery.taskdef function_name(): pass方式二:指定相关参数
@celery.task(bind=True, name='name')def function_name(): pass# task方法参数name : 可以显式指定任务的名字;默认是模块的命名空间中本函数的名字。serializer : 指定本任务的序列化的方法;bind : 一个bool值,设置是否绑定一个task的实例,如果绑定,task实例会作为参数传递到任务方法中,可以访问task实例的所有的属性,即前面反序列化中那些属性base : 定义任务的基类,可以以此来定义回调函数,默认是Task类,我们也可以定义自己的Task类default_retry_delay : 设置该任务重试的延迟时间,当任务执行失败后,会自动重试,单位是秒,默认3分钟;autoretry_for : 设置在特定异常时重试任务,默认False即不重试;retry_backoff : 默认False,设置重试时的延迟时间间隔策略;retry_backoff_max : 设置最大延迟重试时间,默认10分钟,如果失败则不再重试;retry_jitter : 默认True,即引入抖动,避免重试任务集中执行;# 当bind=True时,add函数第一个参数是self,指的是task实例@task(bind=True) # 第一个参数是self,使用self.request访问相关的属性def add(self, x, y): try: logger.info(self.request.id) except: self.retry() # 当任务失败则进行重试,也可以通过max_retries属性来指定最大重试次数方式三:自定义Task基类
import celeryclass MyTask(celery.Task): # 任务失败时执行 def on_failure(self, exc, task_id, args, kwargs, einfo): print('{0!r} failed: {1!r}'.format(task_id, exc)) # 任务成功时执行 def on_success(self, retval, task_id, args, kwargs): pass # 任务重试时执行 def on_retry(self, exc, task_id, args, kwargs, einfo): pass@task(base=MyTask)def add(x, y): raise KeyError()# 方法相关的参数exc : 失败时的错误的类型;task_id : 任务的id;args : 任务函数的参数;kwargs : 键值对参数;einfo : 失败或重试时的异常详细信息;retval : 任务成功执行的返回值;Task的常用属性
Task.name : 任务名称;Task.request : 当前任务的信息;Task.max_retries : 设置重试的最大次数Task.throws : 预期错误类的可选元组,不应被视为实际错误,而是结果失败;Task.rate_limit : 设置此任务类型的速率限制Task.time_limit : 此任务的硬限时(以秒为单位)。Task.ignore_result : 不存储任务状态。默认False;Task.store_errors_even_if_ignored : 如果True,即使任务配置为忽略结果,也会存储错误。Task.serializer : 标识要使用的默认序列化方法的字符串。Task.compression : 标识要使用的默认压缩方案的字符串。默认为task_compression设置。Task.backend : 指定该任务的结果存储后端用于此任务。Task.acks_late : 如果设置True为此任务的消息将在任务执行后确认 ,而不是在执行任务之前(默认行为),即默认任务执行之前就会发送确认;Task.track_started : 如果True任务在工作人员执行任务时将其状态报告为“已启动”。默认是False;三、调用异步任务的三种方法
调用异步任务的三个方法分别是:
# 方法一:这是apply_async方法的别名,但接受的参数较为简单;task.delay()# 方法二:可以接受复杂的参数task.apply_async(args=[arg1, arg2], kwargs={key:value, key:value})# 方法三:可以发送未被注册的异步任务,即没有被celery.task装饰的任务;send_task()方法一:app.send_task
注意: send_task 在发送的时候是不会检查 tasks.add 函数是否存在的,即使为空也会发送成功,所以 celery 执行是可能找不到该函数报错;
方法二:Task.delay
delay 方法是 apply_async 方法的简化版,不支持执行选项,只能传递任务的参数。
方法三:Task.apply_async
apply_async 支持执行选项,它会覆盖全局的默认参数和定义该任务时指定的执行选项,本质上还是调用了 send_task 方法;
自定义发布者、交换机、路由键、队列、优先级、序列方案和压缩方法:
task.apply_async((2,2), compression='zlib', serialize='json', queue='priority.high', routing_key='web.add', priority=0, exchange='web_exchange')四、获取任务结果和状态
由于 celery 发送的都是去其他进程执行的任务,如果需要在客户端监控任务的状态,有如下方法:
r = task.apply_async()r.ready() # 查看任务状态,返回布尔值, 任务执行完成, 返回 True, 否则返回 False.r.wait() # 会阻塞等待任务完成, 返回任务执行结果,很少使用;r.get(timeout=1) # 获取任务执行结果,可以设置等待时间,如果超时但任务未完成返回None;r.result # 任务执行结果,未完成返回None;r.state # PENDING, START, SUCCESS,任务当前的状态r.status # PENDING, START, SUCCESS,任务当前的状态r.successful # 任务成功返回truer.traceback # 如果任务抛出了一个异常,可以获取原始的回溯信息但是一般业务中很少用到,因为获取任务执行的结果需要阻塞,celery使用场景一般是不关心结果的。