二、Quartz任务调度--集群
简介
(1)quartz定时任务调度,quartz最基本的概念就是job,在job内调用具体service完成具体功能,
quartz需要把每个job存储起来,方便调度,quartz存储job方式就分三种,
最常用的也是quartz默认的是RAMJobStore,RAMJobStore顾名思义就是把job的相关信息存储在内存里,
如果用spring配置quartz的job信息的话,所有信息是配置在xml里,当spirng context启动的时候就把xml里的job信息装入内存。
这一性质就决定了一旦JVM挂掉或者容器挂掉,内存中的job信息就随之消失,无法持久化。
另外两种方式是JobStoreTX和JobStoreCMT,使用这两种JobStore,
quartz就会通过jdbc直连或者应用服务器jndi连接数据库,读取配置在数据库里的job初始化信息,
并且把job通过java序列化到数据库里,这样就使得每个job信息得到了持久化,
即使在jvm或者容器挂掉的情况下,也能通过数据库感知到job的状态和信息。
创建mysql数据库表,见文尾: 0. quartz持久化--mysql表
(2)quartz集群各节点之间是通过同一个数据库实例来感知彼此的。
1. 相关jar包引入
<spring.version>3.2.8.RELEASE</spring.version>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
等
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions><!-- 如果单独引入org.slf4j了,此处去掉 -->
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
注意:spring与quartz版本;需要引入spring-context-support.jar包
2. java代码
package com.taiyang.quartz;
/**
* 定时任务执行类--xml文件配置
* @author taiyang
* 2016-05-25 18:36:02
*/
public class TestQuartzCluster implements Job, Serializable{
private static final long serialVersionUID = -6605766126594260961L;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("#################################:TestQuarzCluster");
}
}
/**
* 定时任务管理类
* job、trigger、scheduler
* @author taiyang
* 2016-05-25 18:36:08
*/
public class QuartzManager {
private Scheduler clusterScheduler;//项目启动时注入
public void init() throws SchedulerException{
JobKey jobKey = JobKey.jobKey("customJob_name", "customJob_group");
//clusterScheduler = new StdSchedulerFactory().getScheduler();
JobDetail jobDetail = clusterScheduler.getJobDetail(jobKey);//xml中配置了
TriggerKey triggerKey = TriggerKey.triggerKey("customTrigger_name", "customTrigger_group");
boolean isExists = clusterScheduler.checkExists(triggerKey);
if(isExists){
clusterScheduler.unscheduleJob(triggerKey);//停止调度当前Job任务
}
String cron = (10 % 50) + " 0/1 * ? * *" ;//Cron表达式:每隔一分钟执行一次
Assert.isTrue(CronExpression.isValidExpression(cron), "invalid cron = " + cron);
Date startDate = new Date(System.currentTimeMillis()+ 1*60*1000);//开始执行时间
Map<String, Object> dataMap = new HashMap<String, Object>();//参数
dataMap.put("params", "taiyang");
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.startAt(startDate)
.build();
trigger.getJobDataMap().putAll(dataMap);//传参
clusterScheduler.scheduleJob(trigger);
}
public void setClusterScheduler(Scheduler clusterScheduler) {
this.clusterScheduler = clusterScheduler;
}
}
/**
* 定时任务执行类--动态生成
* @author taiyang
* 2016-05-25 18:36:06
*/
public class CustomQuartzJob implements Job, Serializable{
private static final long serialVersionUID = -6605766126594260962L;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
SchedulerContext schedulerContext = context.getScheduler().getContext();
ApplicationContext applicationContext = (ApplicationContext) schedulerContext.get("applicationContext");
// applicationContext.getBean("BeanName");//获取spring bean实例
JobDataMap dataMap = context.getMergedJobDataMap();
String params = dataMap.getString("params");//获取参数
System.out.println("**************************:" + params);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
3. spring-quartz.xml
<?xml version=&#