任务调度系统-任务依赖的设计
1. 任务依赖需求描述: 例子: 一个作业分为如下子任务: 任务1,任务2,任务3,任务4 执行的顺序为,任务1---》任务2,任务3---》任务4 其中任务2,任务3可以并行执行,我们用下图描述:
这是一个图形结构,我们预设,任务的起始点永远都是一个根节点,不管你业务如何,遵从这个设计是没有难度的,以后的流程,可以并行,也可以串行,任何一个阶段,都能支持并行和串行,因此,我们的子任务关系构成的数据结构为一个图。 2. 任务调度简单流程
3. 数据结构java类描述 //jobConfig 及其子任务的依赖关系描述 public class JobConfig { private Long id; //id private TaskConfig task; //子任务根节点 private String corn; //corn表达式 }
// TaskConfig 描述子任务之间的依赖关系 public class TaskConfig { Long id; String name; //任务名称 private Long jobId; //jobid private String target; //目标任务 List<TaskConfig> parent; //父节点 List<TaskConfig> child; //子节点 } //job类,描述每次任务调度的job public class Job { Long id; JobConfig jobConfig; //所属job_config int status; //执行状态 }
//task类,描述每次任务调度的task public class Task { Long id; TaskConfig taskConfig; //所属task_config Job job; //所属job int status; //执行状态 //父task List<Task> parentList; }
4. 表结构描述 我们需要定义一些表来描述作业子任务之间的静态关系 和执行时的任务状态动态关系 /* job_config表 用来描述job及其子任务的静态关系 */ create table job_config( id, root_task_id --任务根节点 corn --corn表达式 );
/* task_config表,描述job下的子任务之间的静态依赖关系 属于job_config表的子表 */ create table task_config( id,--id name,--任务名称 parent_id --父节点,多个用逗号隔开 child_id --子节点,多个用逗号隔开 job_id --所属的job_id target --目标任务 )
/* job执行状态表
*/ create table job( id, job_config_id,-- 所属job_config status,-- 执行状态 );
/* task 执行状态表 job 的子表 */
create table task( id, task_config_id,-- 所属task_config job_id,-- 所属job status,-- 执行状态 ); 5. 伪代码描述job执行流程
捞取所有job_config表记录,根据corn去触发定时任务 事先构造job_config及其子任务之间的关系,从数据库中根据job_id捞取出 所有的task_config,然后根据其child,parent等构造一个关系对象 JobConfig jobConfig = buildJobConfig(); Job job =buildJob(); //包含持久化job job.setJobConfig(jobConfig); job.execute(); job.execute()方法详细代码: //执行任务 public void execute(){ //构造task树,描述task及其子task的关系 //并持久化到数据库中 Task root = buildRootTask(); root.execute(); } //task.execute 方法 public void execute(){ String target = taskConfig.getTarget(); //是否能执行,要判断先决条件,如果父节点未全部执行完,则跳过此次执行 if(this.canRun()){ boolean success = callTargetTask(target); if(success){ //更新状态为成功 this.updateStatusToSuccess(); }else{ //更新状态为失败 this.updateStatusToFailed(); } } if(childList.size()>0){ //递归执行子任务 for(Task task : childList){ task.execute(); } } } private boolean canRun(){ for(Task task : parentList){ if(!task.isFinished()){ return false; } } return true; } Buildjobconfig代码:
6.任务失败重试设计 待续 分布式任务系统 任务调度系统,和任务执行系统应该分开部署 任务执行系统可以部署多台。调度系统也可以部署多台。 任务调度系统在callTargetTask的时候,用远程调用的形式,这样可以尽可能的提高并发的性能 和系统稳定性。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |