1. 什么是Quartz技术
Quartz是一个流行的开源的调度框架,它可以在特定的时间执行任务或作业。Quartz可以与Java应用程序一起使用,并且可以与几乎所有的主流的关系型数据库一起使用,包括MSSQL数据库。Quartz提供了很多的功能,比如任务调度、任务执行、任务管理、并发控制、任务监听、任务集群化、错误处理等等。Quartz的核心是一个可以控制、管理和监控任务的调度器。
1.1 Quartz的优势
可靠性:Quartz可以保证任务在指定时间内运行,即使是在应用程序或服务器故障的情况下也是如此。
可定制性:Quartz可以根据应用程序特定的需求进行定制和配置。
可伸缩性:Quartz可以很容易地扩展到多个应用程序和环境中。
集群化:多个Quartz实例可以组成一个集群,以便任务的高可用性和负载均衡。
2. Quartz在MSSQL数据库中的应用
Quartz可以与MSSQL数据库完美配合,实现任务调度和执行。在使用Quartz之前,需要在MSSQL数据库中创建相关的表,以存储Quartz调度器的元数据信息。Quartz提供了一些默认的表结构,也可以自定义表结构。首先,我们需要使用Quartz提供的SQL语句来创建默认表。
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_VOLATILE VARCHAR(1) NOT NULL,
IS_STATEFUL VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP));
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP));
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP));
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME));
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP));
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID));
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME));
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME));
在创建完表之后,我们需要在应用程序中配置Quartz调度器。一般来说,我们会创建一个单例的调度器,以此来管理所有的任务。下面是一个简单的示例代码:
StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
3. Quartz任务的创建和执行
Quartz中的每个任务都由两部分组成:Job和Trigger。Job是要执行的任务,Trigger是任务的触发器,它决定何时运行任务。Job和Trigger可以被组合在一起,形成一个任务。
在Quartz中,任务可以有多种类型:
SimpleTrigger:简单触发器,可以触发一次、多次或重复触发。
CronTrigger:Cron触发器,可以基于Cron表达式来触发。
CalendarIntervalTrigger:基于日历的间隔触发器。
3.1 Job的创建和执行
在Quartz中,我们需要实现org.quartz.Job
接口中的execute(JobExecutionContext context)
方法来定义我们具体要执行的任务内容,该方法中有一个JobExecutionContext
对象,该对象中包含了任务的信息。
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 在这里定义要执行的任务内容
}
}
当我们定义好Job之后,我们需要将Job添加到Quartz调度器中。在添加Job时,我们需要指定Job的名称、Job所属的组、Job的类类型和Job的描述。下面是一个简单的示例代码:
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("MyJob", "MyJobGroup")
.withDescription("This is a job to do something.")
.build();
scheduler.addJob(jobDetail, true, true);
我们可以使用JobBuilder
来创建一个JobDetail对象。在这里我们指定了JobMyJob
,该Job位于MyJobGroup
组中,它将会做一些具体的事情,这个描述信息可以帮助我们更好地理解这个Job。
在将Job添加到Quartz调度器中之后,我们需要为Job创建Trigger。Trigger定义了Job要被调度的时间和方式。我们可以使用SimpleTrigger或CronTrigger来创建Trigger。我们需要指定Trigger的名称、所属的组、触发器类型、Start Time、End Time等属性。下面是一个SimpleTrigger的示例代码:
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("MyTrigger", "MyGroup")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(30)
.repeatForever())
.build();
scheduler.scheduleJob(jobDetail, trigger);
在这个示例中,我们使用NewTrigger来创建一个SimpleTrigger。我们将Trigger命名为MyTrigger
,位于MyGroup
组中。触发器将立即启动,每30秒触发一次,重复触发。
3.2 完整的Quartz任务创建和执行代码示例
下面是一个完整的Quartz任务创建和执行代码示例:
public class QuartzSchedulerTest {
public static void main(String[] args) throws SchedulerException {
// 创建一个调度器
StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
// 创建一个JobDetail
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("MyJob", "MyJobGroup")
.withDescription("This is a job to do something.")
.build();
// 创建一个SimpleTrigger
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("MyTrigger", "MyGroup")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(30)
.repeatForever())
.build();
// 将JobDetail和Trigger添加到调度器中
scheduler.scheduleJob(jobDetail, trigger);
}
public static class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 在这里定义要执行的任务内容
}
}
}
4. 结语
Quartz是一种强大的任务调度框架,可以方便地在MSSQL数据库中创建和执行任务。Quartz提供了很多的功能,可以满足不同应用程序的需求。Quartz的可靠性、可定制性、可伸缩性和集群能力,使得它成为开发人员创建和管理任务的首选框架之一。