关于任务调度框架quartz使用(异常处理,解决恢复后多次调度处理)
作者:栗子~~
这篇文章主要介绍了关于任务调度框架quartz使用(异常处理,解决恢复后多次调度处理),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
首先先说说什么是调度框架
大白话所谓的调度框架你可以把它看成一个定时任务管理框架,并且quartz框架是多线程的,
quartz最主要的三大基本特性
(1)调度器 Scheduler(控制调度)
(2)Trigger(定义触发的条件)这里的条件 ,可以用类似于‘0/20 * * * * ?’这种表达式来表示
(3)JobDetail & Job JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中
首先看以下代码讲解了如何新增了一个调度任务
QuartzEntity quartz = new QuartzEntity();
quartz.setJobName("test01");
quartz.setJobGroup("test");
quartz.setDescription("测试任务");
quartz.setJobClassName("com.itstyle.quartz.job.ChickenJob");
quartz.setCronExpression("0/20 * * * * ?");
Class cls = Class.forName(quartz.getJobClassName()) ;
cls.newInstance();
//构建job信息
JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
quartz.getJobGroup())
.withDescription(quartz.getDescription()).build();
// 触发时间点
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
.startNow().withSchedule(cronScheduleBuilder).build();
//交由Scheduler安排触发
scheduler.scheduleJob(job, trigger);不过这里有个问题!,那就是调度任务停止恢复后多次调度的问题。
如何解决,首先在properties配置一文件中配置一行代码
org.quartz.jobStore.misfireThreshold = 5000
这里先介绍下 CronTrigger
这里有三种模式:
withMisfireHandlingInstructionDoNothing
- 不触发立即执行
- 等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
withMisfireHandlingInstructionIgnoreMisfires
- 以错过的第一个频率时间立刻开始执行
- 重做错过的所有频率周期后
- 当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行
withMisfireHandlingInstructionFireAndProceed
- 以当前时间为触发频率立刻触发一次执行
- 然后按照Cron频率依次执行
我们用第一种模式,就是生成Trigger的时候添加第一种模式,以下为代码可以参考下
QuartzEntity quartz = new QuartzEntity();
quartz.setJobName("test01");
quartz.setJobGroup("test");
quartz.setDescription("测试任务");
quartz.setJobClassName("com.itstyle.quartz.job.ChickenJob");
quartz.setCronExpression("0/20 * * * * ?");
Class cls = Class.forName(quartz.getJobClassName()) ;
cls.newInstance();
//构建job信息
JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
quartz.getJobGroup())
.withDescription(quartz.getDescription()).build();
// 触发时间点
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
.withSchedule(cronScheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();
//交由Scheduler安排触发
scheduler.scheduleJob(job, trigger);
好了,以上的方式就能解决恢复后多次调度的问题
停止调度:
try {
//quartz.getJobName() 代表任务id,quartz.getJobGroup()代表任务组
JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
scheduler.pauseJob(key);
} catch (SchedulerException e) {
e.printStackTrace();
return Result.error();
}恢复调度:
try {
//quartz.getJobName() 代表任务id,quartz.getJobGroup()代表任务组
JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
scheduler.resumeJob(key);
} catch (SchedulerException e) {
e.printStackTrace();
return Result.error();
}删除调度:
try {
//quartz.getJobName() 代表任务id,quartz.getJobGroup()代表任务组
TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());
// 停止触发器
scheduler.pauseTrigger(triggerKey);
// 移除触发器
scheduler.unscheduleJob(triggerKey);
// 删除任务
scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup()));
System.out.println("removeJob:"+JobKey.jobKey(quartz.getJobName()));
} catch (Exception e) {
e.printStackTrace();
return Result.error();
} 在调度过程中出现异常怎么办,如何处理
请看以下代码:
/**
* 实现序列化接口、防止重启应用出现quartz Couldn't retrieve job because a required class was not found 的问题
*/
public class TestJob extends AddXxBase implements Job,Serializable {
private final static Logger LOGGER = LoggerFactory.getLogger(TestJob.class);
private static final long serialVersionUID = 1L;
/**
* 模板
* **/
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//任务调度ID
String work = context.getJobDetail().getKey().getName();
try{
//定时器任务start
//定时器任务end
}catch (Exception e){
JobExecutionException e2 = new JobExecutionException(e);
//自动停止job相关的触发器,job停止
//e2.setUnscheduleAllTriggers(true);
//自动任务报错继续执行
e2.setRefireImmediately(true);
LOGGER.error(e2.toString());
}
}
}这里分两种有两种方法:
//自动停止job相关的触发器,job停止 e2.setUnscheduleAllTriggers(true); //自动任务报错继续执行 e2.setRefireImmediately(true);
总结
以上是关于调度任务出现异常后如何处理的相关代码。
好了,这些为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
