• XXL-JOB任务有效期支持实现方案


    概述

    在做数据产品或平台系统时,经常会遇到类似如下截图中,有截至日期的定时调度任务的需求。即定时任务只在指定的开始日期-截至日期里指定的时间里执行。具体的业务需求场景,如营销活动的看板数据的订阅邮件,推送名单的活动,活动(双十一,六一八)结束后就不再需要执行任务。
    在这里插入图片描述
    注:因为使用的Java语言的定时调度平台是XXL-JOB

    需求分析

    查看XXL-JOB管理平台:
    在这里插入图片描述
    发现没有任务开始日期和结束日期的概念。这一点可以在源码com.xxl.job.core.biz.model.JobEntity.java得到验证:

    public class JobEntity implements Serializable {
        private int id;
        private int jobGroup;
        private String jobCron;
        private String jobDesc;
        private Date addTime;
        private Date updateTime;
        private String author;
        private String alarmEmail;
        private String executorRouteStrategy;
        private String executorHandler;
        private String executorParam;
        private String executorBlockStrategy;
        private String executorFailStrategy;
        private String glueType;
        private String glueSource;
        private String glueRemark;
        private Date glueUpdatetime;
        private String childJobKey;
        private String jobStatus;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注:GitHub的代码,找不到这个类,奇怪。

    实现

    针对截图1的表设计如下(省略无关字段):

    create table job (
        job_id          bigint auto_increment primary key,
        job_name        varchar(200)         null comment '订阅名称',
        cron_exp        varchar(200)         null comment 'cron',
        cron_exp_status tinyint(1) default 1 null comment '1表示任务有效,0表示任务关闭',
        start_date      timestamp            null comment '订阅开始时间 yyyy-MM-dd',
        end_date        timestamp            null comment '订阅结束时间 yyyy-MM-dd',
        xxl_job_id      varchar(50)          null comment 'xxl-job id',
        is_active       tinyint(1) default 1 null comment '逻辑删除,1表示有效'
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    新增一个JobHandler,每天0点2分执行,判断当前日期(天粒度)是否达到end_date,如果达到,则设置cron_exp_status=0,并同步到XXL-JOB平台,XXL-JOB平台则不再继续调度此任务。

    
    /**
     * 订阅邮件job有效期结束后,暂停任务
     *
     * @author johnny
     */
    @Slf4j
    @Component
    @JobHander(value = "stopExecuteJobHandler")
    public class StopExecuteJobHandler  extends IJobHandler {
    
        @Resource
        private JobMapper jobMapper;
    
        @Resource
        private JobService jobService;
    
        @Override
        public ReturnT<String> execute(String... strings) throws Exception {
            List<DashboardJob> jobList = jobMapper.getAllStoppedJob();
            if (CollectionUtils.isEmpty(jobList)) {
                log.info(String.format("%s: 没有需要暂停调度的任务", DateUtil.getNow()));
                return ReturnT.SUCCESS;
            }
            for (DashboardJob item : jobList) {
                jobMapper.stopJob(item.getId());
                jobService.disableJob(item.getXxlJobId());
            }
            return ReturnT.SUCCESS;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    对应的mapper.xml文件:

    <select id="getAllStoppedJob" resultType="com.xy.johnny.po.DashboardJob">
        SELECT job_id     AS id,
               xxljob_id  AS xxlJobId
        FROM job WHERE end_date < now() AND isactive = 1 AND cron_exp_status = 1
    select>
    
    <update id="stopJob">
        UPDATE job SET cron_exp_status = 0 WHERE job_id = #{jobId} AND isactive = 1
    update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    封装XXL-JOB提供的JobRestApi的JobService.java

    
    @Resource
    private JobRestApi jobRestApi;
    /**
     * 暂停Job的调度
     */
    public void disableJob(Integer id) throws Exception {
        if (id == null) {
            return;
        }
        ReturnT<String> returnT = jobRestApi.disableJob(id);
        if (returnT.getCode() != CODE) {
            throw new Exception(returnT.getMsg());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    反思

    Quartz任务有任务截至有效期,不明白为啥XXL-JOB调度平台没有这个概念。

    看GitHub动态,XXL-JOB几乎处于停止维护状态,需要forkGit仓库后二次开发。

    参考

    分布式任务调度平台XXL-JOB深度实战

  • 相关阅读:
    redis探索之常用的三种缓存读写策略
    【Docker的使用基础】Mac下利用Docker安装Redis
    网站攻击技术,一篇打包带走!
    CPU版本的pytorch安装
    《软件方法》2023版第1章(10)应用UML的建模工作流-大图
    设计一块PCB 需要知道的流程
    poj1521
    vue项目移动端禁止缩放 左右滑动
    java反射的使用简单例子
    天龙八部科举答题问题和答案(全8/8)
  • 原文地址:https://blog.csdn.net/lonelymanontheway/article/details/127936604