zoukankan      html  css  js  c++  java
  • 对xxl-job进行simpleTrigger并动态创建任务扩展

    业务场景

    需求上要求能实现quartz的simpleTrigger任务,同时还需要动态的创建任务而非在控制面板上创建,查阅xxl-job官方文档发现simpelTrigger其暂时还躺在to do list,而动态创建可以调用JobInfoController其add和start接口(但是有个弊端,start/stop/remove等方法都只要求传送id,这点上可以自己扩展接口实现),还需要放开登录权限,接下来就老夫上去就上一梭子,开干。

    job_info字段调整说明

    CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `job_group` int(11) NOT NULL COMMENT '执行器主键ID',
      `job_cron` varchar(128) DEFAULT NULL COMMENT '任务执行CRON',
      `job_desc` varchar(255) NOT NULL,
      `add_time` datetime DEFAULT NULL,
      `update_time` datetime DEFAULT NULL,
      `author` varchar(64) DEFAULT NULL COMMENT '作者',
      `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
      `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
      `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
      `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
      `executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
      `executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
      `executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失败重试次数',
      `glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
      `glue_source` mediumtext COMMENT 'GLUE源代码',
      `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
      `glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
      `child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
      `ext_reamrk` varchar(255) DEFAULT NULL,
      `job_start_time` bigint(20) DEFAULT NULL COMMENT 'trigger开始时间于当前时间的时间间隔 单位毫秒
    ',
      `job_end_time` datetime DEFAULT NULL COMMENT 'trigger结束时间',
      `job_repeat_count` bigint(7) DEFAULT '-1' COMMENT 'simple_trigger 执行次数 ',
      `job_repeat_interval` bigint(12) DEFAULT NULL COMMENT 'simple_trigger 时间间隔 单位毫秒',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
    
    • job_cron设为空,支持simpleTrigger;
    • ext_reamrk自定义扩展字段,可以根据它来刷选job从而避免start/stop/remove接口只有id作为参数;
    • job_repeat_count,simplerTrigger的执行次数,默认-1即为无限次,0的话是执行1次;
    • job_repeat_interval,simplerTrigger每次执行的时间间隔,单位毫秒;
    • job_start_time,trigger开始时间和当前时间的时间间隔,单位毫秒;
    • job_end_time,trigger结束时间

    重写启动任务

    xxl-job在新建任务的时候只是把job数据保存到数据库里,只有启动的时候才会创建jobDetailtrigger并由scheduler来启动job。

    重写XxlJobDynamicScheduleraddJob方法:根据jobInfo中的值构建cron的trigger还是simple的trigger。

    public static boolean addJob(XxlJobInfo xxlJobInfo) throws SchedulerException {
            String jobName = String.valueOf(xxlJobInfo.getId());
            String cronExpression = xxlJobInfo.getJobCron();
            Integer jobRepeatCount = xxlJobInfo.getJobRepeatCount();
            Long jobRepeatInterval = xxlJobInfo.getJobRepeatInterval();
    
        	// 1、job key
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName);
            JobKey jobKey = new JobKey(jobName);
    
            // 2、valid trigger
            if(scheduler.checkExists(triggerKey)) {
                return true;
            }
    
            // 3.1、corn trigger
            Trigger trigger = null;
            if (!StringUtils.isEmpty(cronExpression)) {
                CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();   // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
                TriggerBuilder<CronTrigger> builder = TriggerBuilder.newTrigger().withIdentity(triggerKey)
                        .withSchedule(cronScheduleBuilder)
                        .endAt(xxlJobInfo.getJobEndTime());
                Optional.ofNullable(xxlJobInfo.getJobStartTime())
                        .ifPresent(start -> builder.startAt(new Date(System.currentTimeMillis() + start)));
                trigger = builder.build();
            } else
            // 3.2、simple trigger
            if (Objects.nonNull(jobRepeatInterval) && Objects.nonNull(jobRepeatCount)) {
                SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInMilliseconds(jobRepeatInterval)
                        .withRepeatCount(jobRepeatCount);
                TriggerBuilder<SimpleTrigger> builder = TriggerBuilder.newTrigger().withIdentity(triggerKey)
                        .withSchedule(simpleScheduleBuilder)
                        .endAt(xxlJobInfo.getJobEndTime());
                Optional.ofNullable(xxlJobInfo.getJobStartTime())
                        .ifPresent(start -> builder.startAt(new Date(System.currentTimeMillis() + start)));
                trigger = builder.build();
            }
            // 3.3、valid trigger
            if(Objects.isNull(trigger)) {
                return true;
            }
    
            // 4、job detail
    		Class<? extends Job> jobClass_ = RemoteHttpJobBean.class;   // Class.forName(jobInfo.getJobClass());
    		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
    
            /*if (jobInfo.getJobData()!=null) {
            	JobDataMap jobDataMap = jobDetail.getJobDataMap();
            	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	
            	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
    		}*/
            
            // 5、schedule job
            Date date = scheduler.scheduleJob(jobDetail, trigger);
    
            logger.info(">>>>>>>>>>> addJob success(quartz), jobDetail:{}, trigger:{}, date:{}", jobDetail, trigger, date);
            return true;
        }
    

    效果图

    img

    image-20190508165249933

    image-20190508165315058

    可以看到将数据库里3任务改为间隔3秒,job_repeat_count为1,任务实际会执行2次。

    额外的工作

    1. 虽然支持cron或simple,但是在控制台节目只能维护cron的trigger,并且优先cron,同时cron设为可以为空,但是管理平台上没有simple的相关数据,如果需要的话要重新修改对应的页面和add和update的逻辑;
    2. job状态取的是trigger的状态,所以可能看到的是simpleTrigger的状态。
    3. 目前job的trigger是在cron和simple中二者取一,但是也可以扩展启动任务的方法,使其支持扩展多trigger,但是triggerKey需要重新定义而非取jobName(因为trigger的hash是triggerKey的hash),本身xxl-job的jobKey取的是job的id,triggerKey取的也是job的id,没有使用到groupName。
  • 相关阅读:
    Let Us Adore 让我们来敬拜祂 中文歌词
    Way Maker 开路者 歌词
    Great Things 伟大的事 歌词
    永活盼望 Living Hope 歌词
    TP 控制器和模型里面order 写法不同
    服务器安全记录
    NOTIC: [8] Trying to get property of non-object
    Declaration of AdminControllerGameController::delete() should be compatible with。。
    vi编辑器操作 快捷键
    Camtasia如何录制小文件视频
  • 原文地址:https://www.cnblogs.com/damonchow/p/10836603.html
Copyright © 2011-2022 走看看