spring 配置动态quartz任务调度

quartz是任务调用框架,和数据库交互实现动态调度任务。可以集群模式,集群在于更加可靠,如果一个节点在执行时间没有调用,在有其它相同配置的集群内其它配置的机器会同样调度,同时它会检查状态,保证同一个任务只会在需要被调用的时间只调用一次。

优势在于动态,可以在执行时暂停或者删除任务。

maven项目实现

spring版本:4.3.18

quartz:2.2.3

maven依赖:

org.quartz-scheduler

quartz

2.2.3

org.quartz-scheduler

quartz-jobs

2.2.3

这次配置的quartz是基于数据库的表配置的,需要用到一些表:

基于mysql的建表语句:

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;  

DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;  

DROP TABLE IF EXISTS QRTZ_LOCKS;  

DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_TRIGGERS;  

DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;  

DROP TABLE IF EXISTS QRTZ_CALENDARS;  


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_NONCONCURRENT VARCHAR(1) NOT NULL,  

IS_UPDATE_DATA VARCHAR(1) NOT NULL,  

REQUESTS_RECOVERY VARCHAR(1) NOT NULL,  

JOB_DATA BLOB NULL,  

PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


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),  

INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),  

FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  

REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (  

SCHED_NAME VARCHAR(120) NOT NULL,  

TRIGGER_GROUP VARCHAR(200) NOT NULL,  

PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


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))  

ENGINE=InnoDB;  


CREATE TABLE QRTZ_LOCKS (  

SCHED_NAME VARCHAR(120) NOT NULL,  

LOCK_NAME VARCHAR(40) NOT NULL,  

PRIMARY KEY (SCHED_NAME,LOCK_NAME))  

ENGINE=InnoDB;  




-- 这是是索引了--------------------------------------------  

CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);  

CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);  


CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);  

CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);  

CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);  

CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);  

CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);  

CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);  

CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);  

CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);  

CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);  

CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);  

CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);  

CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);  


CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);  

CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);  

CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);  

CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);  

CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);  

CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);  


commit;   


这里mysql的InnoDB,在mysql新版本中可有会存在字符过长的问题,VARCHAR(200),默认最长byte为767,200*4超过了767所有会有问题,这里可以打开mysql的innodb_large_prefix = true,默认是为false,或者把varchar改为190,可能会有问题,我这次暂时先改成190,尝试了了一个定时任务,暂时没发现有异常。


配置quartz.properties

#quartz是否自动启动,设为false将不会执行调度

org.quartz.autoStartup=false

#ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)

org.quartz.scheduler.instanceId=AUTO

org.quartz.scheduler.instanceName =DefaultQuartzScheduler

org.quartz.scheduler.rmi.export =false

org.quartz.scheduler.rmi.proxy =false

org.quartz.scheduler.wrapJobExecutionInUserTransaction =false

org.quartz.threadPool.class =org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount =10

org.quartz.threadPool.threadPriority =5

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread =true

org.quartz.jobStore.misfireThreshold =60000

#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

org.quartz.jobStore.class =org.quartz.impl.jdbcjobstore.JobStoreTX

#org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#org.quartz.jobStore.useProperties = true

org.quartz.jobStore.tablePrefix =QRTZ_

org.quartz.jobStore.isClustered =false

org.quartz.jobStore.maxMisfiresToHandleAtATime=1

配置:xml文件,或者直接写在项目xml文件里


      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

      xmlns:tx="http://www.springframework.org/schema/tx"

      xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">


   


        // 延迟加载

//自动启动

// 选定配置文件

//选定数据库


这里的双下划线注释均为写这篇的时间加上去了,程序代码需要删除

配置完成后

@Autowired

private Scheduler scheduler;

自动注入后,通过scheduler的a'pi对定时任务进行操作

添加corn调度任务:

private void addCronTriggerByExpression(HttpServletRequest request, HttpServletResponse response)throws Exception {

//获取触发器名称

    String triggerName = request.getParameter("triggerName");

String cronExpression = request.getParameter("cronExpression");

String jobClass=request.getParameter("jobClass");

if (StringUtils.isEmpty(triggerName) || StringUtils.isEmpty(cronExpression)) {

response.getWriter().println(1);

}

// 验证cronExpression表达式是否合法

    if(!CronExpression.isValidExpression(cronExpression)){

response.getWriter().println(1);

}

JobDetail jobDetail =null;

try{

Class obj=  Class.forName(jobClass);

String jobName = jobClass.substring(jobClass.lastIndexOf(".")+1);

jobDetail = JobBuilder.newJob(obj)

.withIdentity(jobName, Scheduler.DEFAULT_GROUP)

.build();

}catch(Exception e){

e.printStackTrace();

}

// 增加触发器

    schedulerService.schedule(triggerName, cronExpression, jobDetail);

// response.setContentType("text/xml;charset=utf-8");

    response.getWriter().println(0);

}


public void schedule(String name, CronExpression cronExpression,String group,JobDetail jobDetail) {

if (name ==null || name.trim().equals("")) {

name = UUID.randomUUID().toString();

}else{

//在名称后添加UUID,保证名称的唯一性

            name +="&"+UUID.randomUUID().toString();

}

try {

CronTrigger cronTrigger = TriggerBuilder.newTrigger()

.withIdentity(name, group)

.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))//在任务调度器中,使用任务调度器的 CronScheduleBuilder 来生成一个具体的 CronTrigger 对象

                    .build();

//注册作业和触发器

            scheduler.scheduleJob(jobDetail, cronTrigger);

//开始调度任务

//            scheduler.start();

        }catch (SchedulerException e) {

throw new RuntimeException(e);

}

}


添加一个简单定时任务:

/**

* 增加 Simple Trigger

*

* @param request

* @param response

*/

private void addSimpleTrigger(HttpServletRequest request, HttpServletResponse response)throws IOException {

// 获取前台所有配置参数

    Map tempMap = WebUtils.getParametersStartingWith(request,"p_");

Map filterMap =new HashMap();

for (String key : tempMap.keySet()){

filterMap.put (key, (String)tempMap.get(key));

}

String jobClass=request.getParameter("jobClass");

if (StringUtils.isEmpty(filterMap.get(QuartzConstants.STARTTIME))) {

response.getWriter().println(1);

}

JobDetail jobDetail=null;

try {

Class obj=  Class.forName(jobClass);

String jobName = jobClass.substring(jobClass.lastIndexOf(".")+1);

jobDetail = JobBuilder.newJob(obj)

.withIdentity(jobName,Scheduler.DEFAULT_GROUP)

.build();

}catch (Exception e) {

e.printStackTrace();

}

// 增加触发器

    schedulerService.schedule(filterMap,jobDetail);

// response.setContentType("text/xml;charset=utf-8");

    response.getWriter().println(0);

}


//停止触发,移除触发,删除触发

TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,group);

// 停止触发器

            scheduler.pauseTrigger(triggerKey);

// 移除触发器

            return scheduler.unscheduleJob(triggerKey);

// 删除任务

//            return scheduler.deleteJob(JobKey.jobKey(jobname,group));

//重启触发器

scheduler.resumeTrigger(new TriggerKey(triggerName, group));

你可能感兴趣的:(spring 配置动态quartz任务调度)