作业调度框架 Quartz

来源:互联网 发布:python 模拟按键 编辑:程序博客网 时间:2024/06/06 02:15

调度器核心代码:

import nd.sdp.lcreporting.schedule.model.Schedule;import nd.sdp.lcreporting.schedule.service.ScheduleService;import org.quartz.*;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Component;import javax.annotation.Resource;@Componentpublic class QuartzJobScheduler {    private static final String CRON_GROUP = "CRON_QUARTZ_GROUP";    private static final String TRIGGER_ONCE_QUARTZ_GROUP = "TRIGGER_ONCE_QUARTZ_GROUP";    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzJobScheduler.class);    @Resource    private Scheduler scheduler;    @Resource    private ScheduleService scheduleService;    /**     * 通过schedule生成一个quartz调度任务<br/>     * <p>     *     会先删除name为schedule.getName()对应的任务和触发器,重新调度     * </p>     * @param schedule Schedule     * @throws SchedulerException Scheduler exception     */    public void scheduleJob(Schedule schedule) throws SchedulerException {        String name = schedule.getName();        deleteJob(name);        TriggerKey triggerKey = TriggerKey.triggerKey(name, CRON_GROUP);        JobKey jobKey = JobKey.jobKey(name, CRON_GROUP);        Trigger trigger = TriggerBuilder.newTrigger()                .withIdentity(triggerKey)                .withSchedule(                        CronScheduleBuilder.cronSchedule(schedule.getCron())                                .withMisfireHandlingInstructionIgnoreMisfires())                .build();        JobDetail jobDetail = JobBuilder.newJob(QuartzJobExecutor.class)                .withIdentity(jobKey)                .build();        jobDetail.getJobDataMap().put(Schedule.SCHEDULE, schedule);        scheduler.scheduleJob(jobDetail, trigger);    }    /**     * 删除 name为name,group为CRON_GROUP对应的任务和触发器     * @param name job name     * @throws SchedulerException scheduler exception     */    public void deleteJob(String name) throws SchedulerException {        JobKey jobKey = JobKey.jobKey(name, CRON_GROUP);        boolean success = scheduler.deleteJob(jobKey);        if (!success) {            LOGGER.info("job {}-{} not found and deleted.", jobKey.getName(), jobKey.getGroup());        }    }    public void triggerJobNow(Schedule schedule) throws SchedulerException {        schedule.setTriggerOnce(true);        JobDetail jobDetail;        //jobKey name 加上时间窗口后缀,避免拆分后key冲突        Object startTime = schedule.getExtendedProperties().get(ScheduleConstants.TIME_SECTION_START_TIME_KEY);        Object endTime = schedule.getExtendedProperties().get(ScheduleConstants.TIME_SECTION_END_TIME_KEY);        String name = String.format("%s_%s_%s",schedule.getName(), startTime, endTime);        //使用group:TRIGGER_ONCE_QUARTZ_GROUP,与cron任务区分开来        JobKey jobKey = JobKey.jobKey(name, TRIGGER_ONCE_QUARTZ_GROUP);        jobDetail = JobBuilder.newJob(QuartzJobExecutor.class).withIdentity(jobKey)                .storeDurably(true).build();        jobDetail.getJobDataMap().put(Schedule.SCHEDULE, schedule);        try {            this.scheduler.addJob(jobDetail, true);        } catch (SchedulerException e) {            LOGGER.error("triggerJobNow add job fail", e);            throw e;        }        try {            this.scheduler.triggerJob(jobKey);        } catch (SchedulerException e) {            LOGGER.error("triggerJobNow trigger job fail", e);            throw e;        }    }    public int getCurrentlyExecutingJobsCount() throws SchedulerException {        return scheduler.getCurrentlyExecutingJobs().size();    }}

Controller层:

@RestController@RequestMapping(value = "/v0.1/schedules")public class ScheduleController {    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleController.class);    @Resource    private QuartzJobScheduler quartzJobScheduler;    @Resource    private ScheduleService scheduleService;    @RequestMapping(value = "", method = RequestMethod.POST)    public Object createSchedule(@RequestBody Schedule schedule) {        String message = "调度任务创建成功";        schedule = scheduleService.create(schedule);        try {            quartzJobScheduler.scheduleJob(schedule);        } catch (SchedulerException e) {            message = e.getMessage();            LOGGER.error("schedule job error, will delete schedule", e);            scheduleService.delete(schedule.getName());        }        Map<String, String> result = new HashMap<>();        result.put("message", message);        return result;    }    @RequestMapping(value = "", method = RequestMethod.PUT)    public Object reschedule(@RequestBody Schedule schedule) {        String message = "重新调度任务成功";        schedule = scheduleService.update(schedule);        try {            quartzJobScheduler.scheduleJob(schedule);        } catch (SchedulerException e) {            message = e.getMessage();            LOGGER.error("reschedule job error", e);        }        Map<String, String> result = new HashMap<>();        result.put("message", message);        return result;    }    @RequestMapping(value = "{name}", method = RequestMethod.DELETE)    public Object deleteSchedule(@PathVariable String name) {        String message = "调度任务删除成功";        scheduleService.delete(name);        try {            quartzJobScheduler.deleteJob(name);        } catch (SchedulerException e) {            message = e.getMessage();            LOGGER.error("delete schedule job error", e);        }        Map<String, String> result = new HashMap<>();        result.put("message", message);        return result;    }    @RequestMapping(value = "trigger_once", method = RequestMethod.POST)    public Object triggerOnce(@RequestBody TriggerOnceSchedule triggerOnceSchedule) {        String message = "单次触发调度任务成功";        String scheduleName = triggerOnceSchedule.getScheduleName();        if (StringUtils.isEmpty(scheduleName)) {            throw new BizException(ErrorCode.INVALID_ARGUMENT, "schedule_name不能为空");        }        long startTime = triggerOnceSchedule.getTimeSectionStartTime();        long endTime = triggerOnceSchedule.getTimeSectionEndTime();        if (startTime == 0 || endTime == 0 || startTime > endTime) {            throw new BizException(ErrorCode.INVALID_ARGUMENT, "时间窗参数不正确");        }        List<Schedule.ScheduleJob> jobs;        //从数据库中获取Job配置        if (triggerOnceSchedule.isFetchJobsByScheduleName()) {            Schedule scheduleFromDB = scheduleService.find(triggerOnceSchedule.getScheduleName());            if (scheduleFromDB == null) {                throw new BizException(ErrorCode.DATA_NOT_EXIST, "找不到对应的schedule");            }            jobs = scheduleFromDB.getJobs();        } else {            jobs = triggerOnceSchedule.getJobs();        }        List<Schedule> splitScheduleList = splitSchedule(triggerOnceSchedule, jobs);        for (Schedule schedule : splitScheduleList) {            try {                quartzJobScheduler.triggerJobNow(schedule);            } catch (SchedulerException e) {                message = e.getMessage();                LOGGER.error("trigger job error", e);                break;            }        }        Map<String, Object> result = new HashMap<>();        result.put("message", message);        result.put("schedules", splitScheduleList);        return result;    }    private static final long MAX_TIME_SECTION_SIZE = 2592000000L;//30天    private List<Schedule> splitSchedule(TriggerOnceSchedule triggerOnceSchedule, List<Schedule.ScheduleJob> jobs) {        List<Schedule> scheduleList;        long startTime = triggerOnceSchedule.getTimeSectionStartTime();        long endTime = triggerOnceSchedule.getTimeSectionEndTime();        if (triggerOnceSchedule.getSplitSize() > 1) {//按指定大小拆分            long deltaSize = (long) Math.ceil(1.0*(endTime-startTime)/triggerOnceSchedule.getSplitSize());            scheduleList = splitWithDeltaSize(triggerOnceSchedule, jobs, deltaSize);        } else if (endTime - startTime > MAX_TIME_SECTION_SIZE) { //如果时间窗口大于30天,自动拆分成最大30天的窗口大小            scheduleList = splitWithDeltaSize(triggerOnceSchedule, jobs, MAX_TIME_SECTION_SIZE);        } else { //不拆分            scheduleList = new ArrayList<>(1);            Schedule schedule = buildSchedule(triggerOnceSchedule.getScheduleName(), triggerOnceSchedule.getScheduleDesc(),                    jobs, startTime, endTime);            scheduleList.add(schedule);        }        return scheduleList;    }    private List<Schedule> splitWithDeltaSize(TriggerOnceSchedule triggerOnceSchedule, List<Schedule.ScheduleJob> jobs, long deltaSize) {        List<Schedule> scheduleList = new ArrayList<>();        long startTime = triggerOnceSchedule.getTimeSectionStartTime();        long endTime = triggerOnceSchedule.getTimeSectionEndTime();        long splitStartTime = startTime;        long splitEndTime = startTime + deltaSize;        while (splitEndTime <= endTime) {            Schedule schedule = buildSchedule(triggerOnceSchedule.getScheduleName(), triggerOnceSchedule.getScheduleDesc(),                    jobs, splitStartTime, splitEndTime);            scheduleList.add(schedule);            splitStartTime = splitEndTime;            splitEndTime += deltaSize;        }        //把最后一段拼上        if (splitStartTime < endTime) {            Schedule schedule = buildSchedule(triggerOnceSchedule.getScheduleName(), triggerOnceSchedule.getScheduleDesc(),                    jobs, splitStartTime, endTime);            scheduleList.add(schedule);        }        return scheduleList;    }    private Schedule buildSchedule(String name, String desc, List<Schedule.ScheduleJob> jobs, long startTime, long endTime) {        Schedule schedule = new Schedule();        schedule.setJobs(jobs);        schedule.setName(name);        schedule.setDesc(desc);        schedule.getExtendedProperties().put(ScheduleConstants.TIME_SECTION_START_TIME_KEY, startTime);        schedule.getExtendedProperties().put(ScheduleConstants.TIME_SECTION_END_TIME_KEY, endTime);        return schedule;    }}


0 0
原创粉丝点击