实例:
1、代码实现Demo
@Test
public
void
demo01()
throws
InterruptedException{
//获取调度器
SchedulerFactory schedulerFactory =
new
StdSchedulerFactory();
Scheduler scheduler =
null
;
try
{
scheduler = StdSchedulerFactory.getDefaultScheduler();
//引进作业程序这,里的HelloJob是一个Job的继承类,重载的excute方法
JobDetail jobDetail = JobBuilder.newJob(HelloJob.
class
)
.withIdentity(
"helloJob"
,
"group01"
)
.build();
//生成一个触发器,这里这个SimpleTriggerImpl可以被其他的Trigger替换掉的
SimpleTriggerImpl simpleTriggerImpl =
new
SimpleTriggerImpl(
"trigger"
,
"group01"
);
//我使用的是:
//Trigger simpleTriggerImpl = TriggerBuilder.newTrigger().withIdentity("trigger", "group01").build();
simpleTriggerImpl.setStartTime(
new
Date(System.currentTimeMillis()));
simpleTriggerImpl.setRepeatInterval(2000);
simpleTriggerImpl.setRepeatCount(10);
//作业和触发器设置到调度器中
scheduler.scheduleJob(jobDetail, simpleTriggerImpl);
//启动调度器
System.
out
.println(jobDetail.getKey().toString());
scheduler.start();
//注意,在Quartz中,这个调度器的生命周期是和主线程相关的,所有如果主线程退出了,那么调度器也就结束了
Thread. sleep(20000);
}
catch
(SchedulerException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
finally
{
System.
out
.println(HelloJob.
count
);
}
}
2、配置文件实现:Demo
quartz.properties
org.quartz.scheduler.instanceName =
TestScheduler
org.quartz.scheduler.instanceId =
one
org.quartz.threadPool.class =
org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount =
2
org.quartz.threadPool.threadPriority =
4
org.quartz.plugin.jobInitializer.class =
org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames =
jobs.xml #自己的job配置文件
org.quartz.plugin.jobInitializer.failOnFileNotFound =
true
org.quartz.plugin.jobInitializer.scanInterval =
10
org.quartz.plugin.jobInitializer.wrapInUserTransaction =
false
jobs.xml
<?
xml
version
=
'1.0'
encoding
=
'utf-8'
?>
<
job-scheduling-data
xmlns
=
"http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://www.quartz-scheduler.org/xml/JobSchedulingData
http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version
=
"1.8"
>
<
schedule
>
<
job
>
<
name
>
hello
</
name
>
<
group
>
MYJOB_GROUP
</
group
>
<
description
>
The job description
</
description
>
<
job-class
>
com.qunar.xueping.HelloJob
</
job-class
> ##这是为自己的job实现类
<
job-data-map
> #设置JobDataMap key-value
<
entry
>
<
key
>
key
</
key
>
<
value
>
hotdog
</
value
>
</
entry
>
<
entry
>
<
key
>
key2
</
key
>
<
value
>
ketchup, mayo
</
value
>
</
entry
>
</
job-data-map
>
</
job
>
<
trigger
>
<
simple
>
<
name
>
scanTrigger
</
name
>
<
group
>
DEFAULT
</
group
>
<
job-name
>
hello
</
job-name
>
<
job-group
>
MYJOB_GROUP
</
job-group
>
<
repeat-count
>
3
</
repeat-count
>
<
repeat-interval
>
1000
</
repeat-interval
>
</
simple
>
</
trigger
>
</
schedule
>
</
job-scheduling-data
>
注:具体的Schedule调度:
scheduler = StdSchedulerFactory.
getDefaultScheduler
();
schedule.start();
进阶:
1、在调度器中表示一个job或者一个trigger的方式是通过一个JobKey来表示的,
JobKey jobKey = new JobKey("name" , "group");
Scheduler可以对job和Trigger进行一些操作
2、在进行任务调度过程中,可以通过JobDataMap来put Info到Job中去
3、通过SchedulerMetaData metaData = schedule.getMetaData(),里面有一些schedule的常见设置,例如threadPool的size,另外值得注意的是,metaData.getNumberOfJobsException()方法,这个方法返回的是当先执行了多少个job
(疑问:为什么我的Trigger的withRepeatCount设置的是10,但最终job的excute方法执行了11次)
4、注意Job的两个注释:@PersistJobDataAfterExecution @DisallowConcurrentExecution 做什么用,顾名思义啦
5、关于故障的恢复:
在Quartz中对于故障的解决办法是将job persist到数据中,然后通过状态标识Recovering需要恢复的Job
6、Listener:quartz有自己的监听器JobListener,TriggerListstener,SchedulerListerner
举例:JobListener:
public
class
MyJobListener
implements
JobListener{
public
String getName() {
//
TODO
Auto-generated method stub
return
"MyJobListener"
;
}
public
void
jobToBeExecuted(JobExecutionContext context) {
//
TODO
Auto-generated method stub
System.
out
.println(context.getJobDetail().getJobDataMap().getString(
"key"
)+
"jobToBeExecuted----"
);
}
public
void
jobExecutionVetoed(JobExecutionContext context) {
//
TODO
Auto-generated method stub
System.
out
.println(context.getJobDetail().getJobDataMap().getString(
"key"
)+
"jobExecutionVetoed----"
);
}
public
void
jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
//
TODO
Auto-generated method stub
System.
out
.println(context.getJobDetail().getJobDataMap().getString(
"key"
)+
"jobWasExecuted----"
);
}
}
设置Listener:
@Test
public
void
testJob03(){
Scheduler scheduler =
null
;
try
{
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getListenerManager()
.addJobListener(
new
MyJobListener() , KeyMatcher.keyEquals(
new
JobKey(
"hello"
,
"MYJOB_GROUP"
)));
scheduler.start();
Thread. sleep(20000);
}
catch
(Exception e) {
//
TODO
: handle exception
e.printStackTrace();
}
}
7、Quartz的故障恢复机制
默认情况下,Quartz中所提交的任务都是独立的运行在线程中,这意味着机器出现故障或任何原因导致这个线程被干掉了,那么提交的任务就无法继续也无法恢复
解决方法:在出现故障时将任务进行的状态保存下来,Quartz内置了数据库持久化的模块
配置文件:quartz.xml
#配置RAMJobStore
org.quartz.jobStore.class =
org.quartz.simpl.RAMJobStore
#数据库配置
org.quartz.jobStore.misfireThreshold=
60000
org.quartz.jobStore.class=
org.quartz.simpl.RAMJobStore
org.quartz.dataSource.DATA_SOURCE_NAME.driver=
com.mysql.jdbc.Driver
org.quartz.dataSource.DATA_SOURCE_NAME.URL=
jdbc:mysql://localhost:3306/ dbname
org.quartz.dataSource.DATA_SOURCE_NAME.user=
root
org.quartz.dataSource.DATA_SOURCE_NAME.password=
12345
org.quartz.jobStore.class=
org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource=
DATA_SOURCE_NAME
创建数据库:
导入quartz文档中的mysql.sql创建好需要的数据表
故障恢复Demo:
@Test
//@Ignore
public
void
recovery() {
Scheduler scheduler =
null
;
try
{
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.getListenerManager()
.addJobListener(
new
MyJobListener() , KeyMatcher.keyEquals(
new
JobKey(
"hello"
,
"MYJOB_GROUP"
)));
scheduler.start();
//调用schedule的shutdown()方法,这个时候job还没有执行完成,所有会被记录到数据表qrtz_triggers中
scheduler.shutdown();
}
catch
(Exception e) {
//
TODO
: handle exception
e.printStackTrace();
}
try
{
//重新获取schedule调度器,值得注意的是这里获取的调度器同上面的调度器不是同一个对象,而是一个新的调度器
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
//得到group为TestDB的数据中的记录
Set<TriggerKey> triggers = scheduler.getTriggerKeys(GroupMatcher.groupEquals (
"TestDB"
));
Iterator< TriggerKey> iterator = triggers.iterator();
for
(TriggerKey triggerKey : triggers) {
Trigger trigger = scheduler.getTrigger(triggerKey);
//继续执行没执行完的trigger
scheduler.rescheduleJob(triggerKey, trigger);
}
Thread. sleep(40000);
}
catch
(SchedulerException e) {
e.printStackTrace();
}
catch
(InterruptedException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}