任務調度系統-任務依賴的設計

 1.     任務依賴需求描述java

例子:數據庫

一個做業分爲以下子任務:數據結構

任務1,任務2,任務3,任務4併發

執行的順序爲,任務1---》任務2,任務3---》任務4分佈式

其中任務2,任務3能夠並行執行,咱們用下圖描述:高併發

                                                   

這是一個圖形結構,咱們預設,任務的起始點永遠都是一個根節點,無論你業務如何,聽從這個設計是沒有難度的,之後的流程,能夠並行,也能夠串行,任何一個階段,都能支持並行和串行,所以,咱們的子任務關係構成的數據結構爲一個圖。性能

 

2. 任務調度簡單流程ui

 

  1. 首先定義一個job表明一次業務的調度,job維護了任務1到任務4之間的關係。
  2. 找到job的根節點任務1,先執行任務1,由於是根節點,沒有父類,所以沒有先決條件,任務被調度時,便可執行。
  3. 執行完根節點以後,看該節點是否有子節點,沒有則不繼續,有則並行執行全部子節點的任務。
  4. 此時任務2和任務3會被並行調用,咱們假設調用指令先到任務2,任務2發現有1個父節點,且調用指令中表示父節點已經執行完成,那麼就開始執行任務2的調度,同理任務3也是一樣的邏輯。
  5. 任務2和任務3執行完成以後,會前後或者同時調用任務4,咱們這裏爲了不同時併發形成的困擾,任務被調用這個方法要設置成同步,那麼假設任務2先調用任務4,此時咱們在內存中記錄任務2已完成,而且任務4發現本身的2個父節點中,任務3的指令並無來到,所以,這次調度跳過,等待任務3指令的到來。
  6. 當任務3的指令到來,咱們根據jobid,找到以前暫停的job,此時發現任務2,3都執行完成,那麼開始執行任務4,本次業務調度完成。

 

 

3. 數據結構java類描述this

    //jobConfig 及其子任務的依賴關係描述  spa

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的時候,用遠程調用的形式,這樣能夠儘量的提升併發的性能

和系統穩定性。

相關文章
相關標籤/搜索