1 quartz集群模式项目结构如下:
2 applicationcontext.xml 配置如下,配置datasource数据源和导入quartz集群配置
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
beans
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:p=
"http://www.springframework.org/schema/p"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xmlns:cache=
"http://www.springframework.org/schema/cache"
xmlns:task=
"http://www.springframework.org/schema/task"
xmlns:jms=
"http://www.springframework.org/schema/jms"
xmlns:core=
"http://activemq.apache.org/schema/core"
xmlns:mongo=
"http://www.springframework.org/schema/da ta/mongo"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-4.3.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.8.0.xsd
http://www.springframework.org/schema/da ta/mongo http://www.springframework.org/schema/da ta/mongo/spring-mongo-1.8.xsd
http://www.springframework.org/schema/da ta/repository http://www.springframework.org/schema/da ta/repository/spring-repository-1.8.xsd "
>
<!-- 配置扫描的包 -->
<
context:component-scan
base-package=
"com.co de.quartz.job"
/>
<
context:component-scan
base-package=
"com.co de.quartz.method"
/>
<!-- properties引入配置 -->
<
bean
id=
"propertyConfigurer"
class=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>
<
property
name=
"locations"
>
<
list
>
<
value
>classpath:jdbc.properties
</
value
>
</
list
>
</
property
>
</
bean
>
<!-- 数据源 -->
<
bean
id=
"dataSource"
class=
"org.apache.tomcat.jdbc.pool.DataSource"
>
<
property
name=
"poolProperties"
>
<
bean
class=
"org.apache.tomcat.jdbc.pool.PoolProperties"
>
<
property
name=
"driverClassName"
value=
"com.mysql.jdbc.Driver"
/>
<
property
name=
"url"
value=
"${jdbc.url}"
/>
<
property
name=
"username"
value=
"${jdbc.username}"
/>
<
property
name=
"password"
value=
"${jdbc.password}"
/>
<
property
name=
"jmxEnabled"
value=
"true"
/>
<
property
name=
"testWhileIdle"
value=
"false"
/>
<
property
name=
"testOnBorrow"
value=
"true"
/>
<
property
name=
"testOnReturn"
value=
"false"
/>
<
property
name=
"validationInterval"
value=
"30000"
/>
<
property
name=
"validationQuery"
value=
"SELECT 1"
/>
<
property
name=
"timeBetweenEvictionRunsMillis"
value=
"30000"
/>
<
property
name=
"maxActive"
value=
"${jdbc.maxActive}"
/>
<
property
name=
"initialSize"
value=
"${jdbc.initialSize}"
/>
<
property
name=
"maxWait"
value=
"10000"
/>
<
property
name=
"minEvictableIdleTimeMillis"
value=
"30000"
/>
<
property
name=
"maxIdle"
value=
"5"
/>
<
property
name=
"minIdle"
value=
"5"
/>
<
property
name=
"logAbandoned"
value=
"false"
/>
<
property
name=
"removeAbandoned"
value=
"true"
/>
<
property
name=
"removeAbandonedTimeout"
value=
"60"
/>
<
property
name=
"jdbcInterceptors"
value=
"org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
/>
</
bean
>
</
property
>
</
bean
>
<!-- 集群 -->
<
imp ort
resource=
"classpath*:quartz-cluster.xml"
/>
</
beans
>
3 quartz-cluster.xml 配置如下:
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
beans
xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 调度器 -->
<
bean
name=
"quartzScheduler"
class=
"org.springframework.scheduling.quartz.SchedulerFactoryBean"
>
<
property
name=
"dataSource"
>
<
ref
bean=
"dataSource"
/>
</
property
>
<
property
name=
"triggers"
>
<
list
>
<
ref
bean=
"trigger1"
/>
<
ref
bean=
"trigger2"
/>
<
ref
bean=
"trigger3"
/>
</
list
>
</
property
>
<
property
name=
"applicationContextSchedulerContextKey"
value=
"applicationContext"
/>
<!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
<
property
name=
"overwriteExistingJobs"
value=
"true"
/>
<!-- 配置文件路径 -->
<
property
name=
"configLocation"
value=
"classpath:quartz-cluster.properties"
/>
<!-- 自动启动 -->
<
property
name=
"autoStartup"
value=
"true"
/>
<!-- 延迟多少秒执行 -->
<
property
name=
"startupDelay"
value=
"0"
/>
</
bean
>
<!-- 任务1 -->
<
bean
id=
"jobDetail1"
class=
"org.springframework.scheduling.quartz.JobDetailFactoryBean"
>
<
property
name=
"jobClass"
>
<
value
>cn.co
de.quartz.job.ClusterJobBean
</
value
>
</
property
>
<
property
name=
"durability"
value=
"true"
/>
<!-- 属性必须设置为 true,当Quartz服务被中止后,再次启动或集群中其他机器接手任务时会尝试恢复执行之前未完成的所有任务 -->
<
property
name=
"requestsRecovery"
value=
"true"
/>
</
bean
>
<!-- 触发1 10秒调度1次-->
<
bean
id=
"trigger1"
class=
"org.springframework.scheduling.quartz.CronTriggerFactoryBean"
>
<
property
name=
"jobDetail"
ref=
"jobDetail1"
/>
<
property
name=
"cronExpression"
value=
"0/10 * * * * ?"
/>
</
bean
>
<!-- 任务2 -->
<
bean
name=
"jobDetail2"
class=
"org.springframework.scheduling.quartz.JobDetailFactoryBean"
>
<
property
name=
"jobClass"
value=
"cn.co de.quartz.job.DataMapJobBean"
/>
<
property
name=
"durability"
value=
"true"
/>
<
property
name=
"requestsRecovery"
value=
"true"
/>
<!-- 传值 -->
<
property
name=
"jobDataAsMap"
>
<
map
>
<
entry
key=
"targetObject"
value=
"com.custom.package.ClassName"
/>
<
entry
key=
"targetMethod"
value=
"testMethod"
/>
</
map
>
</
property
>
</
bean
>
<!-- 触发2 -->
<
bean
id=
"trigger2"
class=
"org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
>
<
property
name=
"jobDetail"
ref=
"jobDetail2"
/>
<!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<
property
name=
"startDelay"
value=
"0"
/>
<!-- 每15秒调度一次 -->
<
property
name=
"repeatInterval"
value=
"15000"
/>
</
bean
>
<!-- 任务3 -->
<
bean
name=
"methodJob"
class=
"cn.co de.quartz.method.MethodJobDemo"
></
bean
>
<
bean
id=
"jobDetail3"
class=
"org.springframework.scheduling.quartz.JobDetailFactoryBean"
>
<!-- durability 表示任务完成之后是否依然保留到数据库,默认false -->
<
property
name=
"durability"
value=
"true"
/>
<
property
name=
"requestsRecovery"
value=
"true"
/>
<
property
name=
"jobClass"
>
<
value
>cn.co
de.quartz.job.MethodJobBean
</
value
>
</
property
>
<!-- 传值 -->
<
property
name=
"jobDataAsMap"
>
<
map
>
<
entry
key=
"targetObjects"
value=
"methodJob"
/>
<!-- bean名称 -->
<
entry
key=
"targetMethods"
value=
"runTask"
/>
<!-- 方法名称 -->
</
map
>
</
property
>
</
bean
>
<!-- 触发3 -->
<
bean
id=
"trigger3"
class=
"org.springframework.scheduling.quartz.CronTriggerFactoryBean"
>
<
property
name=
"jobDetail"
ref=
"jobDetail3"
/>
<
property
name=
"cronExpression"
value=
"0/10 * * * * ?"
/>
</
bean
>
</
beans
>
4 quartz-cluster.properties 配置如下:
# Clustered
org.quartz.scheduler.instanceName = CHYScheduler1
org.quartz.scheduler.instanceId = AUTO
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.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.txIsolationLevelSerializable = true
org.quartz.jobStore.maxMisfiresToHandleAtATime=10
org.quartz.jobStore.misfireThreshold = 60000
5 ClusterJobBean 测试类如下:
package cn.co
de.quartz.job;
imp ort org.quartz.JobExecutionContext;
imp ort org.quartz.JobExecutionException;
imp ort org.slf4j.Logger;
imp ort org.slf4j.LoggerFactory;
imp ort cn.co
de.quartz.App;
imp ort org.quartz.DisallowConcurrentExecution;
imp ort org.quartz.PersistJobDataAfterExecution;
imp ort org.springframework.scheduling.quartz.QuartzJobBean;
/**
* 集群任务
*
@author
admin
*
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
//不允许并发执行
public
class
ClusterJobBean
extends
QuartzJobBean {
public
static
final
Logger
logger =
LoggerFactory.
getLogger(
App.
class);
@Override
protected
void
executeInternal(
JobExecutionContext
jobexecutioncontext)
throws
JobExecutionException {
logger.
info(
"==================集群任务开始执行======================");
}
}
6 DataMapJobBean 测试类如下:
package cn.co
de.quartz.job;
imp ort java.util.Date;
imp ort org.springframework.scheduling.quartz.QuartzJobBean;
imp ort org.quartz.JobDataMap;
imp ort org.quartz.JobExecutionContext;
imp ort org.quartz.JobExecutionException;
imp ort org.slf4j.Logger;
imp ort org.slf4j.LoggerFactory;
imp ort cn.co
de.quartz.App;
/**
* 演示获取字符串值
*
@author
admin
*
*/
public
class
DataMapJobBean
extends
QuartzJobBean {
public
static
final
Logger
logger =
LoggerFactory.
getLogger(
App.
class);
private
String
targetObject;
private
String
targetMethod;
@Override
public
void
executeInternal(
JobExecutionContext
jobExecutionContext)
throws
JobExecutionException {
logger.
info(
"DataMapJobBean---------------targetObject:"+targetObject+
"-----targetMethod:"+targetMethod +
"-----" +
new
Date());
}
public
void
setTargetObject(
String
targetObject) {
this.
targetObject = targetObject;
}
public
void
setTargetMethod(
String
targetMethod) {
this.
targetMethod = targetMethod;
}
}
7 MethodJobBean 测试类如下:
package cn.co
de.quartz.job;
imp ort org.quartz.JobExecutionContext;
imp ort org.slf4j.Logger;
imp ort org.slf4j.LoggerFactory;
imp ort org.springframework.context.ApplicationContext;
imp ort java.lang.reflect.Method;
imp ort java.util.Date;
imp ort org.quartz.JobExecutionContext;
imp ort org.quartz.JobExecutionException;
imp ort org.springframework.context.ApplicationContext;
imp ort org.springframework.scheduling.quartz.QuartzJobBean;
imp ort cn.co
de.quartz.App;
/**
* 动态映射类和方法
*
@author
admin
*
*/
public
class
MethodJobBean
extends
QuartzJobBean{
public
static
final
Logger
logger =
LoggerFactory.
getLogger(
App.
class);
private
String
targetObjects;
private
String
targetMethods;
private
ApplicationContext
ctx;
@Override
protected
void
executeInternal(
JobExecutionContext
context)
throws
JobExecutionException {
try {
logger.
info(
"MethodJobBean---------targetObjects:"+targetObjects+
"-----targetMethods:"+targetMethods +
"-----" +
new
Date());
Object
otargetObject =
ctx.
getBean(targetObjects);
Method
m =
null;
try {
//方法中的参数是JobExecutionContext类型
m =
otargetObject.
getClass().
getMethod(targetMethods,
new
Class[] {
JobExecutionContext.
class});
m.
invoke(otargetObject,
new
Object[] {context});
}
catch (
SecurityException
e) {
e.
printStackTrace();
}
catch (
NoSuchMethodException
e) {
e.
printStackTrace();
}
}
catch (
Exception
e) {
throw
new
JobExecutionException(e);
}
}
public
void
setApplicationContext(
ApplicationContext
applicationContext) {
this.
ctx = applicationContext;
}
public
void
setTargetObjects(
String
targetObject) {
this.
targetObjects = targetObject;
}
public
void
setTargetMethods(
String
targetMethod) {
this.
targetMethods = targetMethod;
}
}
8 MethodJobDemo 测试类如下:
package cn.co
de.quartz.method;
imp ort org.quartz.JobExecutionContext;
imp ort org.slf4j.Logger;
imp ort org.slf4j.LoggerFactory;
imp ort org.springframework.stereotype.Component;
imp ort cn.co
de.quartz.App;
@Component
public
class
MethodJobDemo {
public
static
final
Logger
logger =
LoggerFactory.
getLogger(
App.
class);
private
String
name;
public
void
runTask(
JobExecutionContext
context){
logger.
info(
"runTask:----------------"+
context.
getJobDetail().
getKey().
getName()+
"---------------");
}
public
String
getName() {
return name;
}
public
void
setName(
String
name) {
this.
name = name;
}
}
9 测试结果