1.写在前面
1.1需求来源
最近有一个需求,假设我们有很多任务需要定时执行甚至定时重复运行,并且其中有一些任务之间可能存在控制依赖和/或数据依赖,甚至我们希望可以利用一些原子任务去组成一个更大的任务。
所以我们需要有一个工具可以将这些任务管理起来:1)解决依赖问题;2)将能并发的任务最大化地并发起来;3)使用简单,只需填写配置文件,不需要写任何代码即可让一堆任务有序地Run起来;4)能够正确调度这些任务的顺序;5)may be more。
我调研了一些已经存在的任务执行引擎,包括FStack。然而试用了一下FStack,发现我不会用,这就很尴尬了。
报着“杀鸡焉用牛刀”的想法,于是最终花了几天自己写了一个可实际运行的工具,即panguan(判官)。
1.2名字来源
这个任务执行引擎被命名为“判官”,就是想给人一种不明觉厉的装X气质。
据百度百科记载,传说中阴曹地府中的判官判处人的轮回生死,对坏人进行惩罚,对好人进行奖励。而该任务执行引擎的主要工作是调度任务的顺序和生存周期,对执行成功和失败的任务进行处理。感觉这个名字很有这个场景的气质,于是配置任务属性的配置文件就顺便被命名为shengsibu.xml了。
1.3目前支持的特性
- 通过XML文件配置任务。
- 支持多任务同时运行并且互不干扰。
- 支持单个任务由多个存在数据依赖和控制依赖或者可以并行执行的子任务组成。子任务可以继续由多个子任务组成,由此可以递归成为一棵复杂的任务树。
- 能够调度各种复杂的任务场景的任务的顺序,使其并发最大化。
- 支持立即执行、定时和重复执行。
- 对任务进行超时检测。
- 展示每一个任务的当前任务状态和运行时间。
- 支持原子任务去调用python和shell的脚本。另外可以不实际去执行脚本而让程序模拟结果,目前返回时间是二项分布~(100,0.05)的随机结果,是否执行成功是p为0.88的伯努利分布的随机结果。
2.工程实践
以下主要简要介绍一些实践中的想法和思路。
2.1异步引擎加线程池
为了支持定时机制、多任务、任务组装、任务依赖等特性,同步的做法显得力不从心,当然也可能是我水平差导致写不出来。于是在这里优先采用了异步引擎加线程池的方案。相对于同步的做法,异步的做法开销更小;然而会导致程序的实现难度增加,也更加难以理解。
我们需要:1)一个异步引擎;2)两个不同方向的线程安全的消息队列,一个是请求MQ,一个是返回MQ;3)一个工作线程池。
异步引擎将每个原子任务派发到请求MQ中,线程中的工作线程监听请求MQ,执行完后插入另一个返回MQ中。异步引擎从返回取回结果。
如下图所示。
我们可以继续推广至一个多机的版本,如下图。
Agent同时监听两个消息队列(一个自身的MQ和一个Center的请求MQ):Agent从Center拉取消息的模式,可以自动实现负载均衡;Center推给Agent的模式,可以指定将任务派发至某个机器,以此提高执行效率。原因可能是这个任务距离数据目标端的物理距离更近。
