上面幾章介紹了quartz監控的幾種方式,下面再介紹一種監聽方式:自定義QuartzJobBean工具
/** * 定時任務處理 * * @author lipeng * */ @DisallowConcurrentExecution public class ScheduleJob extends QuartzJobBean { private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class); private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor"); private final static ISysJobLogService jobLogService = SpringUtils.getBean(ISysJobLogService.class); @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { SysJob job = new SysJob(); BeanUtils.copyBeanProp(job, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); SysJobLog jobLog = new SysJobLog(); jobLog.setJobName(job.getJobName()); jobLog.setJobGroup(job.getJobGroup()); jobLog.setMethodName(job.getMethodName()); jobLog.setMethodParams(job.getMethodParams()); jobLog.setCreateTime(new Date()); long startTime = System.currentTimeMillis(); try { // 執行任務 log.info("任務開始執行 - 名稱:{} 方法:{}", job.getJobName(), job.getMethodName()); ScheduleRunnable task = new ScheduleRunnable(job.getJobName(), job.getMethodName(), job.getMethodParams()); Future<?> future = executor.submit(task); future.get(); long times = System.currentTimeMillis() - startTime; // 任務狀態 0:成功 1:失敗 jobLog.setStatus(Constants.SUCCESS); jobLog.setJobMessage(job.getJobName() + " 總共耗時:" + times + "毫秒"); log.info("任務執行結束 - 名稱:{} 耗時:{} 毫秒", job.getJobName(), times); } catch (Exception e) { log.info("任務執行失敗 - 名稱:{} 方法:{}", job.getJobName(), job.getMethodName()); log.error("任務執行異常 - :", e); long times = System.currentTimeMillis() - startTime; jobLog.setJobMessage(job.getJobName() + " 總共耗時:" + times + "毫秒"); // 任務狀態 0:成功 1:失敗 jobLog.setStatus(Constants.FAIL); jobLog.setExceptionInfo(StringUtils.substring(e.getMessage(), 0, 2000)); } finally { jobLogService.addJobLog(jobLog); } } }
SysJobLogui
/** * 定時任務調度日誌表 sys_job_log * * @author lipeng */ public class SysJobLog extends BaseEntity { private static final long serialVersionUID = 1L; /** ID */ @Excel(name = "日誌序號") private Long jobLogId; /** 任務名稱 */ @Excel(name = "任務名稱") private String jobName; /** 任務組名 */ @Excel(name = "任務組名") private String jobGroup; /** 任務方法 */ @Excel(name = "任務方法") private String methodName; /** 方法參數 */ @Excel(name = "方法參數") private String methodParams; /** 日誌信息 */ @Excel(name = "日誌信息") private String jobMessage; /** 執行狀態(0正常 1失敗) */ @Excel(name = "執行狀態", readConverterExp = "0=正常,1=失敗") private String status; /** 異常信息 */ @Excel(name = "異常信息") private String exceptionInfo; public Long getJobLogId() { return jobLogId; } public void setJobLogId(Long jobLogId) { this.jobLogId = jobLogId; } public String getJobName() { return jobName; } public void setJobName(String jobName) { this.jobName = jobName; } public String getJobGroup() { return jobGroup; } public void setJobGroup(String jobGroup) { this.jobGroup = jobGroup; } public String getMethodName() { return methodName; } public void setMethodName(String methodName) { this.methodName = methodName; } public String getMethodParams() { return methodParams; } public void setMethodParams(String methodParams) { this.methodParams = methodParams; } public String getJobMessage() { return jobMessage; } public void setJobMessage(String jobMessage) { this.jobMessage = jobMessage; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getExceptionInfo() { return exceptionInfo; } public void setExceptionInfo(String exceptionInfo) { this.exceptionInfo = exceptionInfo; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("jobLogId", getJobLogId()) .append("jobName", getJobName()) .append("jobGroup", getJobGroup()) .append("methodName", getMethodName()) .append("methodParams", getMethodParams()) .append("jobMessage", getJobMessage()) .append("status", getStatus()) .append("exceptionInfo", getExceptionInfo()) .append("createTime", getCreateTime()) .toString(); } }
ScheduleRunnablethis
/** * 執行定時任務 * * @author lipeng * */ public class ScheduleRunnable implements Runnable { private static final Logger log = LoggerFactory.getLogger(ScheduleRunnable.class); private Object target; private Method method; private String params; public ScheduleRunnable(String beanName, String methodName, String params) throws NoSuchMethodException, SecurityException { this.target = SpringUtils.getBean(beanName); this.params = params; if (StringUtils.isNotEmpty(params)) { this.method = target.getClass().getDeclaredMethod(methodName, String.class); } else { this.method = target.getClass().getDeclaredMethod(methodName); } } @Override public void run() { try { ReflectionUtils.makeAccessible(method); if (StringUtils.isNotEmpty(params)) { method.invoke(target, params); } else { method.invoke(target); } } catch (Exception e) { log.error("執行定時任務 - :", e); } } }
/** * 建立定時任務 */ public static void createScheduleJob(Scheduler scheduler, SysJob job) { try { // 構建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); // 表達式調度構建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); // 按新的cronExpression表達式構建一個新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId())) .withSchedule(cronScheduleBuilder).build(); // 放入參數,運行時的方法能夠獲取 jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.scheduleJob(jobDetail, trigger); // 暫停任務 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("createScheduleJob 異常:", e); } catch (TaskException e) { log.error("createScheduleJob 異常:", e); } }
/** * 項目啓動時,初始化定時器 */ @PostConstruct public void init() { List<SysJob> jobList = jobMapper.selectJobAll(); for (SysJob job : jobList) { CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, job.getJobId()); // 若是不存在,則建立 if (cronTrigger == null) { ScheduleUtils.createScheduleJob(scheduler, job); } else { ScheduleUtils.updateScheduleJob(scheduler, job); } } }
ScheduleUtils源代碼以下:.net
/** * 定時任務工具類 * * @author lipeng * */ public class ScheduleUtils { private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class); /** * 獲取觸發器key */ public static TriggerKey getTriggerKey(Long jobId) { return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId); } /** * 獲取jobKey */ public static JobKey getJobKey(Long jobId) { return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId); } /** * 獲取表達式觸發器 */ public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId) { try { return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId)); } catch (SchedulerException e) { log.error("getCronTrigger 異常:", e); } return null; } /** * 建立定時任務 */ public static void createScheduleJob(Scheduler scheduler, SysJob job) { try { // 構建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); // 表達式調度構建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); // 按新的cronExpression表達式構建一個新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId())) .withSchedule(cronScheduleBuilder).build(); // 放入參數,運行時的方法能夠獲取 jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.scheduleJob(jobDetail, trigger); // 暫停任務 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("createScheduleJob 異常:", e); } catch (TaskException e) { log.error("createScheduleJob 異常:", e); } } /** * 更新定時任務 */ public static void updateScheduleJob(Scheduler scheduler, SysJob job) { try { TriggerKey triggerKey = getTriggerKey(job.getJobId()); // 表達式調度構建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); CronTrigger trigger = getCronTrigger(scheduler, job.getJobId()); // 按新的cronExpression表達式從新構建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); // 參數 trigger.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.rescheduleJob(triggerKey, trigger); // 暫停任務 if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (SchedulerException e) { log.error("SchedulerException 異常:", e); } catch (TaskException e) { log.error("SchedulerException 異常:", e); } } /** * 當即執行任務 */ public static int run(Scheduler scheduler, SysJob job) { int rows = 0; try { // 參數 JobDataMap dataMap = new JobDataMap(); dataMap.put(ScheduleConstants.TASK_PROPERTIES, job); scheduler.triggerJob(getJobKey(job.getJobId()), dataMap); rows = 1; } catch (SchedulerException e) { log.error("run 異常:", e); } return rows; } /** * 暫停任務 */ public static void pauseJob(Scheduler scheduler, Long jobId) { try { scheduler.pauseJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("pauseJob 異常:", e); } } /** * 恢復任務 */ public static void resumeJob(Scheduler scheduler, Long jobId) { try { scheduler.resumeJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("resumeJob 異常:", e); } } /** * 刪除定時任務 */ public static void deleteScheduleJob(Scheduler scheduler, Long jobId) { try { scheduler.deleteJob(getJobKey(jobId)); } catch (SchedulerException e) { log.error("deleteScheduleJob 異常:", e); } } public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) throws TaskException { switch (job.getMisfirePolicy()) { case ScheduleConstants.MISFIRE_DEFAULT: return cb; case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: return cb.withMisfireHandlingInstructionIgnoreMisfires(); case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: return cb.withMisfireHandlingInstructionFireAndProceed(); case ScheduleConstants.MISFIRE_DO_NOTHING: return cb.withMisfireHandlingInstructionDoNothing(); default: throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); } } }