关于异步任务的说明
任务的多样性
理论上,只要系统能执行的任务,都可以作为任务项,在后台处理,进一步,只要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 | # 定义一个任务模板 |