关于异步任务的说明

  • 任务的多样性

    理论上,只要系统能执行的任务,都可以作为任务项,在后台处理,进一步,只要python语言支持的操作,都可以封装在应用代码中,通过celery异步执行。

  • 任务的持久性

    当代互联网应用,是以用户为中心的服务聚合,考虑到用户心理,后端服务响应时间是左右网站生存期限的重要因素。
    为了提升用户体验,优化响应时间,管理员一般会把耗时久、对用户不可见的功能性任务,调度到系统后台执行(如发送邮件,生成静态文件缓存、其他维护型的定时任务)。
    工具平台使用异步任务,从架构方面讲,更有利于资源的合理利用,以及任务生产者、消费者解耦,提升系统稳定性。

  • 任务的不可预测性

    理论上,一个任务执行完成后,有两种结果,成功或失败。
    此外,如果遭遇停电或主机基础资源瓶颈(如CPU-IO飙高等),还会导致任务出现卡顿或超时等不可预测的情况。

  • 任务复杂度

    任务的发生和发展,均需要一定程度的前置条件,依赖的前置条件不满足,则该任务只能暂停或取消。
    当需要多个前置条件时,任务需要根据不同的前置条件,进行拆分,前置条件越多,涉及面越广,任务复杂度越高。

  • 任务状态

    复杂的任务往往要拆分子任务,相互之间顺序执行(不考虑并行的情况)。
    所以需要定义不同的执行状态,以标记当前任务的所处的阶段。

以上,是我对异步任务的一点思考,欢迎补充。

任务要素

  • 任务ID

    task_id, 任务编号,用于区分一个任务。

  • 任务名称

    task_cname, 任务中文名称。

  • 任务描述

    task_desc, 该字段使用中、英文,对一个任务做简短描述。

  • 任务序号

    task_step, 复杂任务被拆分为多个子任务,每个子任务按照执行顺序,以递增方式,标记在任务链中的序号。

  • 任务模块

    task_module, 可以理解为任务的英文名称,可以用一个或多个单词标记一个任务,只要做到见名知意,方便理解和记忆即可。

  • 任务队列

    taks_queue, 这个字段专为celery应用设计。
    在Redis中可以定义多个不同的Queue,这个字段用来标记任务被发往的Queue(队列通道)。

  • 转换器/投递器

    task_exchange, 转为celery设计,task-task_exchange-task_queue之间具有绑定的关联关系。
    任务投递器,celery中,exchange是任务投递组件,用以关联一个任务和queue.

  • 预处理函数

    task_func, 一个任务被worker(消费者)接收后,执行结果需要进行预处理,才会存入mongodb.
    比如,对比两个目录差异,为了将对比结果在web页面,以树状结构展示,需要使用预处理函数,将生成的差异信息,修改为适配前端tree控件的数据结构。
    这种情况下,将预处理函数提前定义在任务中,后续作为参数发送给消费者,消费者检测到该函数,就会在任务执行结束后,发起数据的预处理。

  • 前端展示标记

    task_panel, 有的任务执行结果,需要在前端展示。
    由于现代前端框架复杂性,任务关联的数据,可能会展示在页面不同位置。
    这个字段是为了适配前端,当任务在前端页面加载后,传递给前端框架的一个标记值。

  • 创建人

    task_creator, 用来标记任务的创建人

  • 任务状态

    task_status, 该字段用来标记任务状态,目前可预见有以下情形:

    - 已启动(或执行中), running
    
    - 等待执行, waiting
    
    - 执行成功, success
    
    - 执行失败, failed
    
    - 已取消, canceled
    
  • 任务执行结果

    task_result, 该字段用来存放任务执行结果。

  • 异常信息

    task_exception, 报错信息,用来排障。

  • 异常堆栈

    task_einfo, python应用可以捕获到详细记录运行时异常信息。

  • 任务参数

    task_args/task_kwargs, 传递给消费者进程的参数信息。

  • 其他常规字段

    • valid

      0 - 表示该任务无效
      1 - 表示该任务有效

    • created_at

      任务创建时间

    • started_at

      任务启动时间

    • ended_at

      任务执行完成时间

结合以上字段元素,我们可以在python应用代码中定义一个任务模板,每当有新任务创建时,填充该模板字段,加入到任务链中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 定义一个任务模板

task_template = {
'task_id':'',
'task_module':'',
'task_cname':'',
'task_desc':'',
'task_step':'',
'taks_queue':'',
'task_exchange':'',
'task_func':'',
'task_panel':'',
'task_creator':'',
'task_status':'',
'task_result':'',
'task_exception':'',
'task_einfo':'',
'task_args': '',
'task_kwargs':'',
'valid':'',
'created_at':'',
'started_at':'',
'ended_at':''
}