xxl-job 定时任务改造

本文介绍如何通过扩展XXL-Job实现任务并行执行的功能,包括新增表设计、任务流程设计、核心代码实现等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、改造背景

因为目前xxl-job 不支持子任务并行执行,所以通过新增几张表来控制任务的父子关系和子任务的并行处理

二、表设计

TD_WORKTASK
名:工作任务信息表,用于储所有的任务信息列表
序号
字段名称
字段类型
字段描述
1
S_TASKNO
String
任务编号
2
S_TASKCMT
String
任务说明
3
S_TASKFLOWNO
String
任务流编号
4
S_FRONTTASKNOLIST
String
前置任务编号列表(暂不使用)
5
S_FRONTTASKFLOWNO
String
前置任务流编号(暂不使用)
TD_WORKTASKFLOW表
名:工作任务流信息表,用于储所有的任务列表
序号
字段名称
字段类型
字段描述
1
S_TASKFLOWNO
String
任务流编号
2
S_TASKFLOWCMT
String
任务流说明
3
I_SUBTASKNUM
String
子任务数目
4
I_TASKSEQ
String
任务顺序
5
S_FRONTTASKFLOWNO
String
前置任务流编号
 TD_WORKTASKTRC表 
 表名:工作任务流跟踪用于日所有的任务执行情况
序号
字段名称
字段类型
字段描述
1
D_TASKDATE
DATE
任务日期
2
S_TASKNO
String
任务编号
3
S_TABNAME
String
表名
4
S_TASKCMT
String
任务说明
5
S_TASKFLOWNO
String
任务流编号
6
S_FRONTTASKNOLIST
String
前置任务编号列表
7
S_FRONTTASKFLOWNO
String
前置任务流编号
8
S_RUNSTATE
String
执行状态
9
S_ISFINISHED
String
是否已完成
10
S_ERRDESC
String
错误描述
11
S_BUSTYPE
String
业务类型
12
I_PARAMSEQNO
int
参数序号
13
TS_SYSUPDATE
Timestamp
系统更新时间
TD_WORKTASKFLOWTRC表
工作任务流跟踪用于日所有的任务执行情况
序号
字段名称
字段类型
字段描述
1
D_TASKDATE
DATE
任务日期
2
S_TASKFLOWNO
String
任务流编号
3
S_TASKFLOWCMT
String
任务流说明
4
I_SUBTASKNUM
int
子任务数目
5
I_FINISHSUBTASKNUM
int
已完成子任务数目
6
I_TASKSEQ
int
任务顺序
7
S_FRONTTASKFLOWNO
String
前置任务流编号
8
S_RUNSTATE
String
执行状态
9
S_ISFINISHED
String
是否已完成
10
TS_SYSUPDATE
   TimeStamp
系统更新时间
TD_BPBASE表  
名:批处理基础数据信息表,用于储所有的任务执行参数信息
序号
字段名称
字段类型
字段描述
1
S_TASKNO
String
任务编号
2
S_OFSYS
String
所属系统
3
S_FILENAME
String
文件名称
4
S_FILEFORMAT
String
文件格式
5
S_FILEPATH
String
文件路径
6
S_ISCOMPRESS
String
是否解压缩
7
S_COMPRESSFORMAT
String
压缩格式
8
S_COMPRESSAFTERNAME
String
解压后文件名称
9
S_ORITBLNAME
String
源表名称
10
S_ORITBLSCHEMA
String
源表schema
11
S_ORITBLDESC
String
原表表名
12
S_TARTBLNAME
String
目标表名称
13
S_TARTBLSCHEMA
String
目标表schema
14
S_ISBACKUP
String
是否保留
15
S_ISLOAD
String
是否导入
16
S_ISEXTRACT
String
是否抽取到批处理层
17
S_ISCLEAN
String
是否清理
18
S_CLEANWHERE
String
清理条件
19
S_ISPUSH
String
是否推送至tdh
20
S_PUSHWHERE
String
推送条件
21
S_PUSHMODE
String
推送模式
22
S_ISBUSPARAMEFFECT
String
是否是业务参数生效
23
S_PPD1
String
预留字段1
24
S_PPD2
String
预留字段2
25
S_PPD3
String
预留字段3
    TS_SYS_STATUS表
    表名:系统状态表
序号
字段名称
字段类型
字段描述
1
I_SEQNO
Long
序列号
2
D_CURACCT
DATE
当前账务日期
3
D_NATURAL
DATE
自然日期
4
S_SYSSTATE
String
系统状态
5
S_CTRSTATE
String
点名状态
6
S_ARCHSTATE
String
归档状态
7
S_FILEARCHSTATE
String
登记簿归档状态
8
S_SYSREMARK
String
系统状态备注
9
TS_SYSUPDATE
Timestamp
系统更新时间

 建表语句

DROP TABLE TD_WORKTASK;
CREATE TABLE `TD_WORKTASK` (
  `S_TASKNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务编号',
  `S_TASKCMT` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务说明',
  `S_TASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流编号',
  `S_FRONTTASKNOLIST` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务编号列表',
  `S_FRONTTASKFLOWNO` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务流编号',
  PRIMARY KEY (`S_TASKNO`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='工作任务信息表'


DROP TABLE TD_WORKTASKFLOW;
CREATE TABLE `TD_WORKTASKFLOW` (
  `S_TASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流编号',
  `S_TASKFLOWCMT` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流说明',
  `I_SUBTASKNUM` INT(32) NOT NULL COMMENT '子任务数目',
  `I_TASKSEQ` INT(8) DEFAULT NULL COMMENT '任务顺序',
  `S_FRONTTASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务流编号'
  
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='工作任务流信息表'


DROP TABLE TD_WORKTASKFLOWTRC;
CREATE TABLE `TD_WORKTASKFLOWTRC` (
  `D_TASKDATE` DATE NOT NULL COMMENT '任务日期',
  `S_TASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流编号',
  `S_TASKFLOWCMT` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流说明',
  `I_SUBTASKNUM` INT(32) NOT NULL COMMENT '子任务数目',
  `I_TASKSEQ` INT(8) DEFAULT NULL COMMENT '任务顺序',
  `S_FRONTTASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务流编号',
  `S_RUNSTATE` TINYINT(1) COMMENT '执行状态',
  `S_ISFINISHED` TINYINT(1) COMMENT '是否已完成',
  `TS_SYSUPDATE` DATETIME COMMENT '系统更新时间'
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='工作任务流跟踪表'


DROP TABLE TD_WORKTASKTRC;
CREATE TABLE `TD_WORKTASKTRC` (
  `D_TASKDATE` DATE NOT NULL COMMENT '任务日期',
  `S_TASKNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务编号',
  `S_TABNAME` VARCHAR(40) CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '表名',
  `S_TASKCMT` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '任务说明',
  `S_TASKFLOWNO` VARCHAR(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务流编号',
  `S_FRONTTASKNOLIST` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务编号列表',
  `S_FRONTTASKFLOWNO` VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '前置任务流编号',
  `S_RUNSTATE` TINYINT(1) COMMENT '执行状态',
  `S_ISFINISHED` TINYINT(1) COMMENT '是否已完成',
  `S_ERRDESC` VARCHAR(2048) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '错误描述',
  `S_BUSTYPE` VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '业务类型',
  `I_PARAMSEQNO` int(32) COMMENT '参数序号',
  `TS_SYSUPDATE` DATE COMMENT '系统更新时间'
) ENGINE=INNODB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='工作任务跟踪表'

三、任务流程设计

四、核心代码设计

任务流及任务表处理的核心方法

/**
    * @Description:查询当前工作日期
    * @Param: []
    * @Teturn: java.util.Date
    * @Date: Created in 2018/11/13 10:13
    */
    public Date queryCurrentDateWork(){
        Date date = null;
        try {
            TsSysStatus t = new TsSysStatus();
            TsSysStatus dto = tsSysstatusMapper.selectOne(t);
            date = dto.getdCuracct();
        } catch (Exception e) {
            log.error("查询当前工作日期异常",e);
        }
        return date;
    }

    /**
    * @Description:
    * @Param: [date, sTaskflowno]
    * @Teturn: boolean
    * @Date: Created in 2019/1/8 9:22
    */
    public boolean doPrepareForTaskFlow(Date date,String sTaskflowno) throws Exception{
        try {
            //1.判断此任务流状态
            TdWorktaskflowtrc  t = new TdWorktaskflowtrc();
            t.setdTaskdate(date);
            t.setsTaskflowno(sTaskflowno);
            TdWorktaskflowtrc runStateDto = tdWorktaskflowtrcMapper.selectOne(t);
            if(runStateDto==null){
                XxlJobLogger.log("根据任务日期:["+date+"],任务流编号:["+sTaskflowno+"],无法查询到相应任务流!");
                throw new RuntimeException("根据任务日期:["+date+"],任务流编号:["+sTaskflowno+"],无法查询到相应任务流!");
            }
            String sRunState = runStateDto.getsRunstate();
            //当任务流状态是已执行状态时,不可重复执行
            if( sRunState.equals(Constants.TASK_STATUS_ENUM.FINISHED.getCode() )){
                log.info("日期:["+date+"],工作流编号:["+sTaskflowno+"]的状态是已执行状态,不可重复执行!");
                XxlJobLogger.log("日期:["+date+"],工作流编号:["+sTaskflowno+"]的状态是已执行状态,不可重复执行!");
                return false;
            }
            //2.将此任务流下的“错误”状态的任务,更新为“可执行”状态
            //where条件
            Example example = new Example(TdWorktasktrc.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("dTaskdate",date);
            criteria.andEqualTo("sTaskflowno",sTaskflowno);
            criteria.andEqualTo("sRunstate",Constants.TASK_STATUS_ENUM.FAILED.getCode());
            TdWorktasktrc recode = new TdWorktasktrc();
            recode.setsRunstate(Constants.TASK_STATUS_ENUM.EXECUTABLE.getCode());
            int num = tdWorktasktrcMapper.updateByExampleSelective(recode,example);
            if(log.isDebugEnabled()){
                log.debug("根据日期:["+date+"],工作流编号:["+sTaskflowno+"],有"+num+"条失败任务被更新为可执行状态任务!");
            }
        } catch (Exception e) {
            log.error("调用任务流准备工作出现异常", e);
        }
        return true;
    }

    /**
    * @Description:执行任务完成后续操作
    * @Param: [workDate, taskFlowNo, taskNo]
    * @Teturn: void
    * @Date: Created in 2019/1/8 9:53
    */
    public void doTaskFinishFollowOp(Date workDate, String taskFlowNo, String taskNo) {
        try {
            int updatecount = 0;
            TdWorktasktrc record;
            TdWorktaskflowtrc taskFlowRecord;
            //(1)更新当前任务状态
            //where条件
            Example example = new Example(TdWorktasktrc.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("dTaskdate",workDate);
            criteria.andEqualTo("sTaskflowno",taskFlowNo);
            criteria.andEqualTo("sTaskno",taskNo);
            record = new TdWorktasktrc();
            record.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
            record.setsIsfinished(Constants.TASK_FINISHED_STATE);
            record.setsErrdesc("");
             updatecount = tdWorktasktrcMapper.updateByExampleSelective(record,example);
            if(log.isDebugEnabled()){
                log.debug("根据日期:["+workDate+"],任务流编号:["+taskFlowNo+"],任务编号:["+taskNo+"],有"+updatecount+"条任务被更新为执行成功状态!");
            }

            //(3)更新任务流已完成子任务数量
            Map param = new HashMap();
            param.put("taskdate",workDate);
            param.put("taskflowno",taskFlowNo);
            batchProcessGeneralMapper.updateTaskFlowFinishNumber(param);
            //(4)更新根任务后置任务
            TdWorktaskflowtrc t = new TdWorktaskflowtrc();
            t.setdTaskdate(workDate);
            t.setsTaskflowno(taskFlowNo);
            TdWorktaskflowtrc s = tdWorktaskflowtrcMapper.selectOne(t);
            int finishNum = s.getiFinishsubtasknum();
            int subNum = s.getiSubtasknum();
            if(finishNum == subNum){
                //(4.1)更新任务流状态为已完成
                //where条件
                Example taskFlowExample = new Example(TdWorktaskflowtrc.class);
                Example.Criteria taskFlowCriteria = taskFlowExample.createCriteria();
                taskFlowCriteria.andEqualTo("dTaskdate",workDate);
                taskFlowCriteria.andEqualTo("sTaskflowno",taskFlowNo);
                taskFlowRecord = new TdWorktaskflowtrc();
                taskFlowRecord.setsIsfinished(Constants.TASK_FINISHED_STATE);
               taskFlowRecord.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
                tdWorktaskflowtrcMapper.updateByExampleSelective(taskFlowRecord,taskFlowExample);
                //(4.2)更新后置任务流中的根任务状态为可执行状态
                //查找后置任务流编号
                TdWorktaskflowtrc postObjCond = new TdWorktaskflowtrc();
                postObjCond.setsFronttaskflowno(taskFlowNo);
                postObjCond.setdTaskdate(workDate);
                TdWorktaskflowtrc laterResult = tdWorktaskflowtrcMapper.selectOne(postObjCond);
                if(laterResult!=null){
                    //后置任务流编号
                    String laterTaskFlowNo = laterResult.getsTaskflowno();
                    if(StringUtils.isNotBlank(laterTaskFlowNo)){
                        //where条件
                        Example e = new Example(TdWorktasktrc.class);
                        Example.Criteria c = e.createCriteria();
                        c.andEqualTo("dTaskdate",workDate);
                        c.andEqualTo("sTaskflowno",laterTaskFlowNo);
                        record = new TdWorktasktrc();
                        record.setsRunstate(Constants.TASK_STATUS_ENUM.EXECUTABLE.getCode());
                        tdWorktasktrcMapper.updateByExampleSelective(record,e);
                    }
                }
                //创建发布事件并发布
                TaskEvent<TdWorktaskflowtrc> taskEvent = TaskEvent.newInstance(t);
                TaskEventPublisher.publishEventAsync(taskEvent);
            }
        } catch (Exception e) {
            log.error("根据日期:["+workDate+"],任务流编号:["+taskFlowNo+"],任务编号:["+taskNo+"],执行任务完成后续操作异常", e);
        }
    }

    public void doTaskFailFollowOp(Date workDate,String taskFlowNo,String taskNo,String sErrdesc){
        try{
            if(log.isDebugEnabled()){
                log.info("任务日期:["+ DateUtils.formatDate(workDate,"yyyyMMdd")+"],任务流编号:["+taskFlowNo+"],任务编号:["+taskNo+"]出现异常!");
            }
            Example example = new Example(TdWorktasktrc.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("sTaskno",taskNo);
            criteria.andEqualTo("dTaskdate",workDate);
            criteria.andEqualTo("sTaskflowno",taskFlowNo);

            //限制错误最大字符数量
            if(sErrdesc!=null) {
                if (sErrdesc.length() > Constants.MAX_LENGTH_OF_ERROR_INFO) {
                    sErrdesc = sErrdesc.subSequence(0, Constants.MAX_LENGTH_OF_ERROR_INFO).toString();
                }
            }

            TdWorktasktrc record = new TdWorktasktrc();
            record.setsErrdesc(sErrdesc);
            record.setsRunstate(Constants.TASK_STATUS_ENUM.FAILED.getCode());
            tdWorktasktrcMapper.updateByExampleSelective(record,example);
        } catch (Exception e) {
            log.error("根据日期:["+workDate+"],任务流编号:["+taskFlowNo+"],任务编号:["+taskNo+"],任务执行失败后续操作异常", e);
        }
    }


    /**
     * 通过工作日期和任务流编号,修改任务流和任务状态为已执行状态
     * @param date
     * @param taskFlowNo
     * @throws Exception
     */
    public void updateTaskStateByRunned(Date date,String taskFlowNo) throws Exception{
        try{
            //(1)更新任务编号为已执行状态
            //where条件
            Example example = new Example(TdWorktasktrc.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("dTaskdate",date);
            criteria.andEqualTo("sTaskflowno",taskFlowNo);

            TdWorktasktrc record = new TdWorktasktrc();
            record.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
            record.setsIsfinished(Constants.TASK_FINISHED_STATE);
            record.setsErrdesc("");
            tdWorktasktrcMapper.updateByExampleSelective(record,example);
            //(2)更新任务流为已执行状态
            //where条件
            Example taskFlowExample = new Example(TdWorktaskflowtrc.class);
            Example.Criteria taskFlowCriteria = taskFlowExample.createCriteria();
            taskFlowCriteria.andEqualTo("dTaskdate",date);
            taskFlowCriteria.andEqualTo("sTaskflowno",taskFlowNo);
            TdWorktaskflowtrc taskFlowRecord = new TdWorktaskflowtrc();
            taskFlowRecord.setsIsfinished(Constants.TASK_FINISHED_STATE);
            taskFlowRecord.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
          tdWorktaskflowtrcMapper.updateByExampleSelective(taskFlowRecord,taskFlowExample);
            //(4.1)更新任务流状态为已完成
            //where条件
            taskFlowExample = new Example(TdWorktaskflowtrc.class);
            taskFlowCriteria = taskFlowExample.createCriteria();
            taskFlowCriteria.andEqualTo("dTaskdate",date);
            taskFlowCriteria.andEqualTo("sTaskflowno",taskFlowNo);
            taskFlowRecord = new TdWorktaskflowtrc();
            taskFlowRecord.setsIsfinished(Constants.TASK_FINISHED_STATE);
            taskFlowRecord.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
            tdWorktaskflowtrcMapper.updateByExampleSelective(taskFlowRecord,taskFlowExample);
            //(4.2)更新后置任务流中的根任务状态为可执行状态
            Map p = new HashMap();
            p.put("taskdate",date);
            p.put("fronttaskflowno",taskFlowNo);
            tdWorktasktrcMapper.updatePostTaskState(p);
            //(4.3)更新任务流中的所有任务状态为可执行状态
            //where条件
            Example taskExample = new Example(TdWorktasktrc.class);
            Example.Criteria  taskCriteria = taskExample.createCriteria();
            taskCriteria.andEqualTo("dTaskdate",date);
            taskCriteria.andEqualTo("sTaskflowno",taskFlowNo);
            TdWorktasktrc taskRecord = new TdWorktasktrc();
            taskRecord.setsIsfinished(Constants.TASK_FINISHED_STATE);
            taskRecord.setsRunstate(Constants.TASK_STATUS_ENUM.FINISHED.getCode());
            tdWorktasktrcMapper.updateByExampleSelective(taskRecord,taskExample);
        } catch (Exception e){
            log.error("通过任务流编号:"+taskFlowNo+"修改任务流和任务的状态为已执行状态出现异常", e);
        }
    }

    /**
     * 在规定时间内轮旬判断任务流状态,直到为完成状态,如超出规定时间,则抛出RunTimeException
     * @param taskFlowNo
     */
    public boolean judgePreTaskFlow(Date taskDate,String taskFlowNo,long waitTime) throws Exception{
        long start = DateUtils.getSysDate().getTime();
        String taskFlowCmt =findTaskFlowNoCmt(taskDate,taskFlowNo);
        long end = 0;
        boolean keepRunning = true;
        while(keepRunning){
            TdWorktaskflowtrc tdWorktaskflowtrc = new TdWorktaskflowtrc();
            tdWorktaskflowtrc.setdTaskdate(taskDate);
            tdWorktaskflowtrc.setsTaskflowno(taskFlowNo);
            TdWorktaskflowtrc tdWorktaskflowtrcResultDto = tdWorktaskflowtrcMapper.selectOneNonUseCache(tdWorktaskflowtrc);
            String sRunstate = tdWorktaskflowtrcResultDto.getsRunstate();
            if(sRunstate.equals(Constants.TASK_STATUS_ENUM.FINISHED.getCode())){
                log.info("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流已执行成功");
                XxlJobLogger.log("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流已执行成功");
                return true;
            }else{
                TdWorktasktrc tdWorktasktrc = new TdWorktasktrc();
                tdWorktasktrc.setdTaskdate(taskDate);
                tdWorktasktrc.setsTaskflowno(taskFlowNo);
                int num = tdWorktasktrcMapper.getErrorTaskNum(taskDate,taskFlowNo);
                if(num!=0){
                    log.info("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流已存在错误任务,不在等待");
                    XxlJobLogger.log("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流已存在错误任务,不在等待");
                    return false;
                }else{
                    log.info("正在等待[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流完成");
                    XxlJobLogger.log("正在等待[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]前置任务流完成");
                    end = DateUtils.getSysDate().getTime();
                    long diff = (end-start)/1000;
                    if(waitTime < diff){
                        log.info("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]"+"前置任务流超时,后续任务流不在执行");
                        XxlJobLogger.log("[前置任务流编号:"+taskFlowNo+",前置任务流名称:"+taskFlowCmt+"]"+"前置任务流超时,后续任务流不在执行");
                        return false;
                    }
                }
            }
            Thread.sleep(15000);
        }
        return true;
    }

    public String findTaskFlowNoCmt(Date taskDate,String taskFlowNo) throws Exception{
        TdWorktaskflowtrc dto = new TdWorktaskflowtrc();
        dto.setdTaskdate(taskDate);
        dto.setsTaskflowno(taskFlowNo);
        TdWorktaskflowtrc tdWorktaskflowtrc = tdWorktaskflowtrcMapper.selectOneNonUseCache(dto);
        String taskFlowCmt = "";
        if(tdWorktaskflowtrc!=null){
            taskFlowCmt = tdWorktaskflowtrc.getsTaskflowcmt();
        }
        return taskFlowCmt;
    }
    
    /**
    * @Description:根据工作日期、任务流编号获取前置任务流编号
    * @Param: [taskDate, taskFlowNo]
    * @Teturn: java.lang.String
    * @Date: Created in 2019/3/21 14:31
    */
    public String findFrontTaskFlowNo(Date taskDate,String taskFlowNo) throws Exception{
        String frontTaskFlowNo = null;
        TdWorktaskflowtrc dto = new TdWorktaskflowtrc();
        dto.setdTaskdate(taskDate);
        dto.setsTaskflowno(taskFlowNo);
        TdWorktaskflowtrc tdWorktaskflowtrc = tdWorktaskflowtrcMapper.selectOneNonUseCache(dto);

        if(tdWorktaskflowtrc!=null){
            frontTaskFlowNo = tdWorktaskflowtrc.getsFronttaskflowno();
        }
        return frontTaskFlowNo;
    }

任务IJobHandler 代码示例

package com.xxl.job.executor.jobhandler.batchpdf.handler;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.executor.base.ExecuteTaskConfig;
import com.xxl.job.executor.jobhandler.batchpdf.service.BatchPdfService;
import com.xxl.job.executor.jobhandler.common.persistence.service.BatchProcessGeneralService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;


import java.util.Date;


/**
* @Author:shaowei
* @Description:批量生成pdf[任务流编号:117]
* @Date:Created in 2019/1/3 11:02
* @Modified By:
*/
@JobHandler(value="batchpdf")
@Component
public class BatchPdfHandler extends IJobHandler {

    @Autowired
    private BatchProcessGeneralService batchProcessGeneralService;

    @Autowired
    private ExecuteTaskConfig executeTaskConfig;

    @Autowired
    private BatchPdfService batchPdfService;

    final String CURRENT_TASK_FLOW_NO = "117";

    @Override
    public ReturnT<String> execute(String param) throws Exception {


        Date date = batchProcessGeneralService.queryCurrentDateWork();
        String frontTaskFlowNo = batchProcessGeneralService.findFrontTaskFlowNo(date, CURRENT_TASK_FLOW_NO);
        long waitTime = executeTaskConfig.getTaskFlowNoWaitTime108();
        Boolean flag = batchProcessGeneralService.judgePreTaskFlow(date, frontTaskFlowNo, waitTime);
        if (flag) {
            if (batchProcessGeneralService.doPrepareForTaskFlow(date, CURRENT_TASK_FLOW_NO)) {
                batchPdfService.batchPdfHandle(date, CURRENT_TASK_FLOW_NO);
                XxlJobLogger.log("批量生成pdf :success");
                return ReturnT.SUCCESS;
            } else {
                return ReturnT.FAIL;
            }
        } else {
            return ReturnT.FAIL;
        }
    }
}

任务核心线程代码样例

package com.xxl.job.executor.jobhandler.batchpdf.thread;
import com.jcraft.jsch.ChannelSftp;
import com.xxl.job.config.spring.SpringContextHolder;
import com.xxl.job.executor.base.constant.Constants;
import com.xxl.job.executor.jobhandler.batchpdf.chain.IPDFGenerator;
import com.xxl.job.executor.jobhandler.batchpdf.chain.PDF;
import com.xxl.job.executor.jobhandler.batchpdf.chain.PDFGenerateChain;
import com.xxl.job.executor.jobhandler.batchpdf.chain.PDFGeneratorContainer;
import com.xxl.job.executor.jobhandler.batchpdf.service.BatchPdfService;
import com.xxl.job.executor.jobhandler.batchpdf.service.InWarehouseFlowService;
import com.xxl.job.executor.jobhandler.common.persistence.dto.TdBpbase;
import com.xxl.job.executor.jobhandler.common.persistence.dto.TdWorktasktrc;
import com.xxl.job.executor.jobhandler.common.persistence.mapper.TdBpbaseMapper;
import com.xxl.job.executor.jobhandler.common.persistence.service.BatchProcessGeneralService;
import com.xxl.job.executor.jobhandler.common.persistence.service.CommonService;
import com.xxl.job.executor.jobhandler.common.persistence.service.TdWorktasktrcService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;

/**
* @Description:批量报表生成
* @Param:
* @Teturn:
* @Date: Created in 2019/7/10 10:36
*/
public class BatchPdfThread extends Thread {


    private static Log log = LogFactory.getLog(BatchPdfThread.class);
    private Date taskDate;
    private String taskFlowNo;
    private Map<String, TdBpbase> baseMap;
    private LinkedBlockingQueue<TdWorktasktrc> taskQueue;
    private boolean keepRunning = true;
    /**
     * 用countDownLatch 来判断任务是否执行完成,执行成功,countDownLatch - 1
     */
    private CountDownLatch countDownLatch;

    public BatchPdfThread(Date taskDate, String taskFlowNo, LinkedBlockingQueue<TdWorktasktrc> taskQueue, Map<String, TdBpbase> baseMap, CountDownLatch countDownLatch) {
        this.taskDate = taskDate;
        this.taskFlowNo = taskFlowNo;
        this.taskQueue = taskQueue;
        this.baseMap = baseMap;
        this.countDownLatch = countDownLatch;
    }

    public BatchPdfThread() {
        super();
    }

    @Override
    public void run() {
        log.info(Thread.currentThread().getName() + "线程启动");
        BatchProcessGeneralService batchProcessGeneralService = SpringContextHolder.getBean(BatchProcessGeneralService.class);
        BatchPdfService batchPdfService = SpringContextHolder.getBean(BatchPdfService.class);
        PDFGenerateChain pdfGenerateChain = new PDFGenerateChain();
        while (keepRunning) {
            TdWorktasktrc taskObject = null;
            String taskNo = null;
            try {
                taskObject = taskQueue.poll();
                if (taskObject != null) {
                    taskNo = taskObject.getsTaskno();
                    PDF pdf = new PDF(taskDate, taskNo);
                    pdfGenerateChain.generatePDF(pdf);
                    //处理任务-结束
                    doTaskFinishFollowOp(taskDate, taskFlowNo, taskNo);
                    countDownLatch.countDown();
                } else {
                    keepRunning = false;
                }
            } catch (Exception e) {
                log.error("线程[" + Thread.currentThread().getName() + "]执行批量报表生成异常", e);
                batchProcessGeneralService.doTaskFailFollowOp(taskDate, taskFlowNo, taskNo, e.getMessage());
            }
        }
        log.info("无可执行任务," + Thread.currentThread().getName() + "线程结束");
    }

    public synchronized void doTaskFinishFollowOp(Date date, String taskFlowNo, String taskNo) throws Exception {


        try {
            BatchProcessGeneralService batchProcessGeneralService = SpringContextHolder.getBean(BatchProcessGeneralService.class);
            batchProcessGeneralService.doTaskFinishFollowOp(date, taskFlowNo, taskNo);
        } catch (Exception e) {
            log.error("执行任务完成后续操作异常", e);
            throw e;
        }
    }

    public void doTaskFailFollowOp(Date date, String taskFlowNo, String taskNo, String errorInfo) throws Exception {
        try {
            BatchProcessGeneralService batchProcessGeneralService = SpringContextHolder.getBean(BatchProcessGeneralService.class);
            batchProcessGeneralService.doTaskFailFollowOp(date, taskFlowNo, taskNo, errorInfo);
        } catch (Exception e) {
            log.error("执行任务失败后续操作异常", e);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行客-编码爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值