简单说下什么是Quartz,做一个简介:
What is the Quartz Job Scheduling Library?
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
官网地址:http://www.quartz-scheduler.org/
这个是官网介绍,翻译总结一下就是:quartz是一个开源的工作任务日常安排,能在任何的java虚拟机中作为一个独立的程序跑起来,能创造一个简单或者复杂的日常任务去执行。简单来说就是定时器,java中自带的定时器是Timer,Quartz也是一个定时器,但是比Timer强大。
Quartz的强大之处?
1.与spring整合,简单,方面,可靠,使用简单。
与spring的整合(使用注解的方式最灵活):
配置文件:
spring-quartz.xml
<!-- task任务扫描注解 -->
<task:annotation-driven />
定时任务类(前提需要给Spring扫描器进行扫描):
package com.lgy.schedule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.lgy.service.MyserviceInterface;
@Component
public class TestSchedule {
@Autowired
private MyserviceInterface myserviceInterface;
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void run() {
System.out.println(myserviceInterface.fun(99999));
System.out.println("执行了这个线程!");
}
}
@Scheduled是Quartz的一个注解类,cron是定时表达式。
这样并整合结束了,该run方法每5秒钟并会整合一次。
2.动态的添加任务,修改定定时任务时间,删除定时任务,关闭定时任务。
package com.jeecg.timer;
import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import com.base.util.SpringContextUtil;
import com.jeecg.entity.AneTimer;
/**
* ****************************************************************
* 文件名称 : QuartzManager.java
* 创建时间 : 2015年9月17日 上午10:19:46
* 文件描述 : 定时任务管理类
* 版权声明 :
* 修改历史 : 2015年9月17日 1.00 初始版本
*****************************************************************
*/
@Service
public class QuartzManager {
private final static Logger log= Logger.getLogger(QuartzManager.class);
// private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
private static SchedulerFactoryBean schedFact ;
private static Scheduler sched;
/**
* 获取调度工厂
* @return
*/
public static SchedulerFactoryBean getSchedulerFactory(){
if (schedFact == null) {
schedFact = (SchedulerFactoryBean)SpringContextUtil.getBean("schedulerFactoryBean");
}
return schedFact;
}
@Autowired
public void setSchedFact(SchedulerFactoryBean schedFact) {
QuartzManager.schedFact = schedFact;
}
/**
* 获取调度器
* @return
* @throws SchedulerException
*/
public static Scheduler getScheduler() throws SchedulerException{
if (sched==null) {
sched = getSchedulerFactory().getScheduler();
}
return sched;
}
/**
* @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
*
* @param myJob
*
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void addJob(AneTimer myJob,Class cls) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:addJob start");
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (null == cronTrigger) {
JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName,jobGroup).build();
cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup)
.withSchedule(CronScheduleBuilder.cronSchedule(myJob.getCronexpression())).build();
// cronTrigger.getJobDataMap().put("jobEntity", myJob);
scheduler.scheduleJob(jobDetail, cronTrigger);
//启动一个定时器
if (!scheduler.isShutdown()) {
scheduler.start();
}
} else {
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(myJob.getCronexpression()))
.build();
scheduler.rescheduleJob(triggerKey, cronTrigger);
}
//等待启动完成
// Thread.sleep(TimeUnit.SECONDS.toMillis(10));
} catch (Exception e) {
e.printStackTrace();
}
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:addJob end");
}
/**
* @Description: 暂停一个任务
*
* @param myJob
*
*/
public static void pasueOneJob(AneTimer myJob) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:pasueOneJob start");
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger trigger = scheduler.getTrigger(triggerKey);
// if(null==trigger){
// log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
// return;
// }
JobKey jobKey = trigger.getJobKey();
scheduler.pauseJob(jobKey);
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:pasueOneJob end");
}
/**
* @Description: 重启一个任务
*
* @param myJob
*
*/
public static void resOneJob(AneTimer myJob) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:resOneJob start");
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger trigger = scheduler.getTrigger(triggerKey);
// if(null==trigger){
// log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
// return;
// }
scheduler.rescheduleJob(triggerKey, trigger);
// Thread.sleep(TimeUnit.MINUTES.toMillis(10));
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:resOneJob end");
}
/**
* @Description: 修改一个任务的触发时间
*
* @param jobName
*/
public static void modifyJobTime(AneTimer myJob, String time) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:modifyJobTime start");
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
myJob.setCronexpression(time);
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(myJob.getCronexpression());
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder)
.build();
scheduler.rescheduleJob(triggerKey, cronTrigger);
// Thread.sleep(TimeUnit.MINUTES.toMillis(60));
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:modifyJobTime end");
}
/**
* @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
*
* @param jobName
*
*/
public static void removeJob(AneTimer myJob) {
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob start");
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger trigger = scheduler.getTrigger(triggerKey);
if(null==trigger){
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
return;
}
JobKey jobKey = trigger.getJobKey();
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(jobKey);// 删除任务
//Thread.sleep(TimeUnit.MINUTES.toMillis(10));
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob end");
}
/**
*
* 方法表述 获得执行器状态
* @return
* String
*/
public static String getStatus(AneTimer myJob){
String state = "NONE";
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
//trigger state
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
state = triggerState.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
return state;
}
/**
* 是否存在任务
* 方法表述
* @param myJob
* @return
* boolean
*/
public static boolean hasTrigger(AneTimer myJob){
boolean isHas = true;
try {
Scheduler scheduler = getScheduler();
// 唯一主键
String jobName = myJob.getJobname();
String jobGroup = myJob.getJobgroup();
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
Trigger trigger = scheduler.getTrigger(triggerKey);
if(null==trigger){
log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>method:removeJob trigger is NULL ");
isHas = false;
}
} catch (SchedulerException e) {
isHas = false;
e.printStackTrace();
}
return isHas;
}
/**
* @Description:启动所有定时任务
*
*/
public static void startJobs() {
try {
Scheduler sched = getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*
*/
public static void shutdownJobs() {
try {
Scheduler sched = getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
3.提供存储化方式
Quartz提供两种基本作业存储类型。第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储。区别和联系用下图表示:
类型 | 优点 | 缺点 |
RAMJobStore | 不要外部数据库,配置容易,运行速度快 | 因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制 |
JDBC作业存储 | 支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务 | 运行速度的快慢取决与连接数据库的快慢 |
参考配置文件如下:
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#============================================================================
# Configure JobStore
#============================================================================
#org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.CascadingClassLoadHelper
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#havent cluster spring
#org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = false
org.quartz.jobStore.maxMisfiresToHandleAtATime=1
#==============================================================
#Non-Managed Configure Datasource if you don't use spring cluster
#==============================================================
#org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.myDS.URL = jdbc\:mysql\://192.168.204.159\:3306/test
#org.quartz.dataSource.myDS.user = root
#org.quartz.dataSource.myDS.password = root
#org.quartz.dataSource.myDS.maxConnections =10