JAVA Quartz 任务调度框架

以往写任务调度,碰到秒级任务调度,必不可免的使用sleep来做延时。

在实际操作中非常不方便,而且因为任务本身存在执行时间问题,必不可免的造成不准确的sleep。搜索了下网上相关开源框架,发现Quartz最适合我的任务场景的应用。可惜本身JAVA语言并不是很好,又无奈英文水平有限,磕磕碰碰遇到很多问题。

在IDE部分,选用Eclipse4.5+jdk1.8。框架部分,选用Quartz2.2.3。

网上大多例子均不是基于2.2.3的导致函数方法上存在差异,无法执行。而且略微复杂的功能框架javadoc内均没详细说明,例子也没写清楚。一个简单运行例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package Test;
import java.util.Date;
 
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
 
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class QuartzManager {
private static Logger log = LoggerFactory.getLogger(QuartzManager.class);
private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
public void run() throws Exception {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
// 新建任务 任务名,任务组,任务执行类
JobDetail jobDetail = newJob(HelloJob.class).withIdentity("jobName, "jobGroupName")
.build();
 
// 触发器 cron格式每秒执行
CronTrigger trigger = newTrigger().withIdentity("triggerName", "triggerGroupName")
.withSchedule(cronSchedule("0/1 * * * * ?"))
.build();
 
// 任务绑定触发器
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
// 延时10秒
Thread.sleep(10L * 1000L);
// 实际引用中大家一般不会直接getKey所以例子内用字符串转换方式
// 这个地方坑了我至少2小时,网上例子里均是直接使用字符串的
// 但是2.2.3内参数类型为JobKey和TriggerKey
// 获取 JobKey
JobKey jobKey =new JobKey("jobName","jobGroupName");
// 获取 TriggerKey
TriggerKey triggerKey =new TriggerKey("triggerName","triggerGroupName");
// 停止触发器
sched.pauseTrigger(triggerKey);
// 停止任务
sched.pauseJob(jobKey);
// 删除任务
sched.deleteJob(jobKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
 
public static void main(String[] args) throws Exception {
 
QuartzManager example = new QuartzManager();
example.run();
 
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package Test;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
 
public class HelloJob implements Job {
 
    private static Logger _log = LoggerFactory.getLogger(HelloJob.class);
    public HelloJob() {
    	System.out.println("Hello World! - " + new Date());
    }
    public void execute(JobExecutionContext context)
        throws JobExecutionException {
        _log.info("Hello World! - " + new Date());
    }
 
}

因为使用了slf4j,所以一定要在bin目录放置log4j.xml,配置信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
  <appender name="default" class="org.apache.log4j.ConsoleAppender">
    <param name="target" value="System.out"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="[%p] %d{dd MMM hh:mm:ss.SSS aa} %t [%c]%n%m%n%n"/>
    </layout>
  </appender>
 
 
 <logger name="org.quartz">
   <level value="info" />
 </logger>
 <logger name="Test">
   <level value="info" />
 </logger>
  <root>
    <level value="info" />
    <appender-ref ref="default" />
  </root>
 
 
</log4j:configuration>

如果想使用数据库来持久化任务的话,可以用框架源码下的docs\dbTables目录内的sql自己创建数据库。
以mysql为例子,Quartz需要使用InnoDb请使用tables_mysql_innodb.sql而并不是tables_mysql.sql,除非你的数据库默认不是MyISAM。
然后在导入成功后,在项目内引用mysql-connector-java库,再在bin目录增加配置文件quartz.properties内容如下。

1
2
3
4
5
6
7
8
9
10
11
12
org.quartz.scheduler.instanceName = Test
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS
 
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/task?characterEncoding=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 5

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注