Spring4.2+quartz2.2集群
2019独角兽企业重金招聘Python工程师标准>>>
不了解定时器概念的朋友们可以参考:
基于 Quartz 开发企业级任务调度应用
1、maven创建工程
2、导入依赖 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.test</groupId><artifactId>quartz-test</artifactId><version>1.0.0</version><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><junit.version>4.12</junit.version><spring.version>4.2.1.RELEASE</spring.version><mysql.version>5.1.36</mysql.version><quartz.version>2.2.3</quartz.version></properties><dependencies><!-- junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><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>${quartz.version}</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>${quartz.version}</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.19</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency></dependencies><build><finalName>quartz-test</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.3</version><configuration><source>1.7</source><target>1.7</target><encoding>UTF-8</encoding></configuration></plugin><!-- maven-assembly-plugin --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>2.7</version><configuration><encoding>UTF-8</encoding></configuration></plugin></plugins></build></project>
3、配置quartz.properties
#============================================================== #Configure Main Scheduler Properties #============================================================== org.quartz.scheduler.instanceName = mapScheduler org.quartz.scheduler.instanceId = AUTO #============================================================== #Configure JobStore #============================================================== 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.maxMisfiresToHandleAtATime = 1 org.quartz.jobStore.misfireThreshold = 120000 org.quartz.jobStore.txIsolationLevelSerializable = true org.quartz.jobStore.selectWithLockSQL = SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE #============================================================== #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 #============================================================== #Skip Check Update #update:true #not update:false #============================================================== org.quartz.scheduler.skipUpdateCheck = true #============================================================================ # Configure Plugins #============================================================================ org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin org.quartz.plugin.shutdownhook.cleanShutdown = true
4、配置 db.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE
username=root
quartz.password=123456
5、配置 applicationContext.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" 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:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/beansclasspath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsdhttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contextclasspath:/org/springframework/context/config/spring-context-3.0.xsdhttp://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/taskhttp://www.springframework.org/schema/task/spring-task-3.0.xsd"><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><value>classpath:db_server.properties</value></property></bean><!-- 数据源定义,使用 druid 连接池 --><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"init-method="init" destroy-method="close"><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${quartz.password}" /><property name="maxActive" value="1000" /><property name="initialSize" value="30" /><property name="maxWait" value="60000" /><property name="timeBetweenEvictionRunsMillis" value="60000" /><property name="minEvictableIdleTimeMillis" value="300000" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="false" /><property name="testOnReturn" value="false" /><!-- 开启Druid的监控统计功能 --><property name="filters" value="stat" /></bean></beans>
6、配置 applicationContext-quartz.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" xmlns:context="http://www.springframework.org/schema/context"xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"><!-- ********************1、配置处理日志任务 bean******************** --><bean name="analysisScheduleTask-bean" class="com.test.quartz.AnalysisScheduleTask"></bean><!-- ********************2、动态创建日志记录表 jobdetail******************** --><bean id="createTableTask-jobdetail"class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><!-- durability 表示任务完成之后是否依然保留到数据库,默认false --><property name="durability" value="true" /><property name="requestsRecovery" value="true" /><property name="jobClass"><!-- MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的,因此在把QUARTZ 的 TASK 序列化进入数据库时就会抛错。 所以我们要自己实现MethodInvokingJobDetailFactoryBean的功能,这里用MyDetailQuartzJobBean 替换。 --><value>com.test.quartz.MyDetailQuartzJobBean</value></property><property name="jobDataAsMap"><map><!-- 关联bean --><entry key="targetObject" value="analysisScheduleTask-bean" /><!-- 方法名 --><entry key="targetMethod" value="createTableTask" /></map></property><property name="description" value="创建表信息任务" /></bean><bean id="secheduleTask-jobdetail"class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><!-- durability 表示任务完成之后是否依然保留到数据库,默认false --><property name="durability" value="true" /><property name="requestsRecovery" value="true" /><property name="jobClass"><!-- MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的,因此在把QUARTZ 的 TASK 序列化进入数据库时就会抛错。 所以我们要自己实现MethodInvokingJobDetailFactoryBean的功能,这里用MyDetailQuartzJobBean 替换。 --><value>com.test.quartz.MyDetailQuartzJobBean</value></property><property name="jobDataAsMap"><map><!-- 关联bean --><entry key="targetObject" value="analysisScheduleTask-bean" /><!-- 方法名 --><entry key="targetMethod" value="secheduleTask" /></map></property><property name="description" value="调度任务栈" /></bean><!-- ********************3、配置触发器时间******************** --><bean id="createTableTask-trigger"class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><!-- 关联日志 --><property name="jobDetail" ref="createTableTask-jobdetail" /><!-- 时间配置 --><property name="cronExpression" value="0/1 * * * * ?" /><!-- 描述信息 --><property name="description" value="创建表信息" /></bean><bean id="secheduleTask-trigger"class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><!-- 关联日志 --><property name="jobDetail" ref="secheduleTask-jobdetail" /><!-- 时间配置 --><property name="cronExpression" value="0/1 * * * * ?" /><!-- 描述信息 --><property name="description" value="调度任务栈" /></bean><!-- ********************4、注册调度任务******************** --><bean id="mapScheduler" lazy-init="false" autowire="no"class="org.springframework.scheduling.quartz.SchedulerFactoryBean"destroy-method="destroy"><property name="dataSource"><ref bean="dataSource" /></property><!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 --><property name="overwriteExistingJobs" value="true" /><!--必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 --><property name="startupDelay" value="5" /><!-- 设置自动启动 --><property name="autoStartup" value="true" /><property name="triggers"><list><ref bean="createTableTask-trigger" /><ref bean="secheduleTask-trigger" /></list></property><property name="applicationContextSchedulerContextKey" value="applicationContext" /><property name="configLocation" value="classpath:quartz.properties" /></bean></beans>
7、创建MyDetailQuartzJobBean.java
注:此步骤的原因: quartz整合Spring注入Service时空指针异常问题解决
public class MyDetailQuartzJobBean extends QuartzJobBean {private String targetObject;private String targetMethod;private ApplicationContext ctx;@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {try {// LogUtils.Log("execute [" + targetObject + "] at once>>>>>>");Object otargetObject = ctx.getBean(targetObject);Method m = null;try {m = otargetObject.getClass().getMethod(targetMethod, new Class[] { JobExecutionContext.class }); // 方法中的参数是JobExecutionContext类型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 setTargetObject(String targetObject) {this.targetObject = targetObject;}public void setTargetMethod(String targetMethod) {this.targetMethod = targetMethod;}}
8、创建ScheduleTask.java
public class AnalysisScheduleTask { /*** 调度创建表,方法中的参数是JobExecutionContext类型,要使MyDetailQuartzJobBean中的executeInternal方法中利用反射机制调用到相应的方法*/ public void createTableTask(JobExecutionContext context){ System.out.println("@创建表..."+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));} /*** 调度任务栈,方法中的参数是JobExecutionContext类型,要使MyDetailQuartzJobBean中的executeInternal方法中利用反射机制调用到相应的方法*/ public void secheduleTask(JobExecutionContext context){ System.out.println("@调度任务栈..."+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));} /*** 删除任务栈,方法中的参数是JobExecutionContext类型,要使MyDetailQuartzJobBean中的executeInternal方法中利用反射机制调用到相应的方法*/ public void deleteTask(JobExecutionContext context){ System.out.println("deleteTask"); } }
9、创建启动Client.java
public class Client {private static Logger logger = LoggerFactory.getLogger(Client.class);public static void main(String[] args) {initquartz();}private static void initquartz() {ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext.xml","classpath:applicationContext-quartz.xml"});}}
10、导入quartz数据库表
quartz 2.x和quartz1.x的数据库表是不一样的。要导入对应版本的数据库表
## Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar## PLEASE consider using mysql with innodb tables to avoid locking issues## In your Quartz properties file, you'll need to set# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate#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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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(200) 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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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))ENGINE=InnoDB DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;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 DEFAULT CHARSET=utf8;CREATE TABLE QRTZ_LOCKS(SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME VARCHAR(40) NOT NULL,PRIMARY KEY (SCHED_NAME,LOCK_NAME))ENGINE=InnoDB DEFAULT CHARSET=utf8;commit;
在Spring中使用Quartz任务调度支持集群(转载)
虽然在Quartz上有配置Quartz集群Clustering ,但是在Spring中使用Quartz任务调度并支持集群系统却有些问题,下面介绍解决办法:
环境:(环境非常重要,注意版本号)
Spring-1.2.7:spring.jar-1.2.7.jar
Quartz-1.5.2:quartz-1.5.2.jar,quartz-oracle-1.5.2.jar
Oracle10G:
org.springframework.scheduling.quartz.CronTriggerBean与Quartz版本依赖情况:
NOTE: This convenience subclass does not work with trigger persistence in Quartz 1.6,
due to a change in Quartz's trigger handling. Use Quartz 1.5 if you rely on trigger
persistence based on this class, or the standard Quartz CronTrigger class instead.org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean在使用
org.quartz.impl.jdbcjobstore.JobStoreTX的支持情况:Note: JobDetails created via this FactoryBean are not serializable and thus not suitable
for persistent job stores. You need to implement your own Quartz Job as a thin wrapper for
each case where you want a persistent job to delegate to a specific service method.
所以,Quartz集群只支持JDBCJobStore存储方式,而MethodInvokingJobDetailFactoryBean不能序列化存储job数据到数据库,
所以需要手工编写任务调度类继承QuartzJobBean,否则报如下错误:
ERROR [org.springframework.web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'schedulerFactoryBean' defined
in ServletContext resource [/WEB-INF/classes/tim-quartz.xml]: Invocation of init method failed;
nested exception is org.quartz.JobPersistenceException: Couldn't store job: Unable to serialize JobDataMap for insertion
into database because the value of property 'methodInvoker' is not serializable:
org.springframework.scheduling.quartz.MethodInvoki ngJobDetailFactoryBean [See nested exception: java.io.NotSerializableException:
Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable:
org.springframework.scheduling.quartz.MethodInvoki ngJobDetailFactoryBean]
类路径上的quartz.properties:
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = falseorg.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = trueorg.quartz.jobStore.misfireThreshold = 60000
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
#============================================================================
# Configure Main Scheduler Properties
#============================================================================org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure JobStore
#============================================================================org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = SYS_org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000#============================================================================
# Configure Datasources
#============================================================================#org.quartz.dataSource.myDS.jndiURL = java:comp/env/jdbc/psmis
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@10.150.131.33:1521:psmis
org.quartz.dataSource.myDS.user = psmis
org.quartz.dataSource.myDS.password = psmis33
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
创建数据库表结构:在下载的包quartz-1.5.2.zip\quartz-1.5.2\docs\dbTables\tables_oracle.sql
调度类,SysScheduleManagerImpl.java:
package com.sunrise.psmis.sysmanagement.service.impl;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;import com.sunrise.psmis.webapp.util.ContextUtil;
public class SysScheduleManagerImpl extends QuartzJobBean{
protected final Log logger = LogFactory.getLog(getClass());
private String targetObject;
private String targetMethod;
protected void executeInternal(JobExecutionContext context) throws JobExecutionException{
// System.out.println(jobData.getData() + " 第一个已经被执行了!!");
try
{
ApplicationContext ctx =ContextUtil.getContext();Object otargetObject=ctx.getBean(targetObject);
Method m=null;
try {
m = otargetObject.getClass().getMethod(targetMethod, new Class[] {});
m.invoke(otargetObject, new Object[] {});
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
catch(Exception e)
{
throw new JobExecutionException(e);
}
finally
{
logger.debug("end");
}
}public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
}public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}}
//ContextUtil类可以在应用启动的Listener里初始化Spring的ApplicationContext,将ApplicationContext保存在static变量里
applicationContext-service.xml:
<bean id="exampleJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.sunrise.psmis.sysmanagement.service.impl.SysScheduleManagerImpl</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="targetObject" value="ecOwnUnstopWorksheetManager"/>
<entry key="targetMethod" value="execSyncPaymeny"/>
</map>
</property>
</bean>
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="exampleJob" />
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0 2 * * * ?" />
</bean><bean id="seqJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>com.sunrise.psmis.sysmanagement.service.impl.SysScheduleManagerImpl</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="targetObject" value="sysIdManager"/>
<entry key="targetMethod" value="callProSeqEvalute"/>
</map>
</property>
</bean>
<bean id="seqTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="seqJob" />
<!-- run every morning at 6 AM -->
<property name="cronExpression" value="0 0 0,1,2 * * ?" />
</bean><bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<ref bean="seqTrigger"/>
</list>
</property>
<property name="schedulerContextAsMap">
<map>
<entry key="sysIdManager">
<ref bean="sysIdManager" />
</entry>
<entry key="ecOwnUnstopWorksheetManager">
<ref bean="ecOwnUnstopWorksheetManager" />
</entry>
</map>
</property>
</bean>前辈,你这篇文章就是及时雨啊。我这几天正在搞这个jobstore。可是现在遇到个问题,放狗都搜不到什么东西。
008-10-08 15:48:09,806 org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:205) - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.quartz.SchedulerFactoryBean' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.quartz.SchedulerException: Registration of jobs and triggers failed: closeResultSet Caused by: org.quartz.SchedulerException: Registration of jobs and triggers failed: closeResultSet at org.springframework.scheduling.quartz.SchedulerFactoryBean.registerJobsAndTriggers(SchedulerFactoryBean.java:798)
请前辈指点一二,叩谢
啊,前辈,刚才那个问题莫名其妙就没了。现在是另外一个问题,我的xml定义的contrigger是这样的: 在applicationContext.xml里:
<?xml version="1.0" encoding="UTF-8"?> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="configLocation" value="/WEB-INF/quartz.properties"/><property name="triggers"><list><ref bean="cronTertioRespParseTrigger"/></list></property> </bean>
然后在具体模块的xml里定义了:
<?xml version="1.0" encoding="UTF-8"?> <bean class="org.springframework.scheduling.quartz.CronTriggerBean" id="cronTertioRespParseTrigger"><property name="jobDetail"><bean class="com.foss.main.customObject.MyMethodInvokingJobDetailFactoryBean"><property name="targetObject" ref="terRspParseCronService"/><property name="targetMethod" value="processFiles"/><!-- <property name="concurrent"><value>false</value></property> --></bean></property><property name="volatility"><value>true</value></property><property name="cronExpression"><value>0 0/5 * * * ?</value></property> </bean>
现在的问题是,当weblogic server起来后,报:
2008-10-08 16:40:00,107 org.quartz.core.JobRunShell.run(JobRunShell.java:202) - Calling execute on job DEFAULT.com.foss.main.customObject.MyMethodInvokingJobD etailFactoryBean#308737 2008-10-08 16:40:00,117 org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFact oryBean.java:242) - Could not invoke method 'null' on target object [null] java.lang.IllegalStateException: prepare() must be called prior to invoke() on MethodInvoker at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:267) at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java: 224) at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86) at org.quartz.core.JobRunShell.run(JobRunShell.java:203) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) 2008-10-08 16:40:00,157 org.quartz.core.JobRunShell.run(JobRunShell.java:208) - Job DEFAULT.com.foss.main.customObject.MyMethodInvokingJobDetailFactoryBean#30 8737 threw a JobExecutionException: org.quartz.JobExecutionException: Could not invoke method 'null' on target object [null] [See nested exception: java.lang.IllegalStateException: prepare() mus t be called prior to invoke() on MethodInvoker]
其中,MyMethodInvokingJobDetailFactoryBean是我wripper的MethodInvokingJobDetailFactoryBean 是不是我xml里config的job不对呢?请前辈指教
你的错误报:Could not invoke method 'null' on target object [null] ; 说明的你的配置有问题。如果你是要集群环境跑,那就不能用MethodInvokingJobDetailFactoryBean,好像你的MyMethodInvokingJobDetailFactoryBean也是继承这个的。如果不是集群环境,那么用MethodInvokingJobDetailFactoryBean很方便。
如果不是集群环境参考:
<bean id="exampleJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject" ref="ecOwnUnstopWorksheetManager" /><property name="targetMethod" value="execSyncPaymeny" /><property name="concurrent" value="false" /> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"><property name="jobDetail" ref="exampleJob" /><!-- run every morning at 6 AM --><property name="cronExpression" value="0 2 * * * ?" /> </bean>
大侠,我是要在集群环境跑。我的目的是要在cluster的环境下,同一时间只能有一个app server 跑scheduled 好的一个job, 我做的那个MyMethodInvokingJobDetailFactoryBean的确是继承的MethodInvokingJobDetailFactoryBean,因为MethodInvokingJobDetailFactoryBean不是序列化的。但是我在MyMethodInvokingJobDetailFactoryBean不知道该怎么重写execute()。。。。。。。 刚才又去试了你给的SysScheduleManagerImpl.java,可是在做ContextUtil的遇到路径问题。在我的applicationContext里,有定义quartz.property的路径: <property name="configLocation" value="WEB-INF/quartz.properties" /> 这个在weblogic parse xml file的时候是工作的。但是当用FileSystemXmlApplicationContext(xml file list)的时候,就找不到了。我要是改成FileSystemXmlApplicationContext能找到的,weblogic parse的时候就找不到了。晕啊
大侠,我终于搞出来了。没有用那个ContextUtil 而是在xml file里面加一句:
<bean id="Scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="configLocation" value="WEB-INF/quartz.properties" /><property name="applicationContextSchedulerContextKey"><value>applicationContext</value></property><property name="triggers"><list>
然后在SysScheduleManagerImpl.java里:
ApplicationContext ctx = (ApplicationContext) context.getScheduler().getContext().get("applicationContext"); Object otargetObject=ctx.getBean(targetObject);
转自:在Spring中使用Quartz任务调度支持集群(转载)
参考:Spring Scheduler定时器原理分析
Spring Quartz动态管理定时任务及相关问题总结
Spring 整合 Quartz 实现动态定时任务(附demo)
转载于:https://my.oschina.net/anxiaole/blog/1358779
Spring4.2+quartz2.2集群相关推荐
- tomcat8.0.15+spring4.1.2的集群下共享WebSocketSession?
环境:nginx+Tomcat服务器 A B C 问题:如果用户 1 访问由服务器 A socket服务 ,用户2 由服务器 C socket服务 ,此时如果用户 1, 2 想通过 socket ...
- quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析 引言 quartz集群架构 调度器实例化 调度过程 触发器的获取 触发trigger: Job执行过程: 总结: 附: 引言 quratz是目前最为成 ...
- redis集群安装和java应用
首先是在linux下装redis3.0 以下是我在centos 6.5安装成功的.内容主要是http://redisdoc.com/topic/cluster-tutorial.html 的内容加上走 ...
- 项目中使用Quartz集群分享--转载
原文:http://hot66hot.iteye.com/blog/1726143 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享 一:CRM对定时任务的依赖 ...
- quartz分布式集群部署并且可视化配置job定时任务
2019独角兽企业重金招聘Python工程师标准>>> 项目使用quartz框架完成了定时任务集群部署调度,并且对quartz进一步封装完成在web界面可动态配置定时任务.定时任务如 ...
- HOW-TO:具有MySQL的JEE应用程序中具有集群功能的Quartz Scheduler
Quartz Scheduler是Java世界中最流行的调度库之一. 过去,我主要在Spring应用程序中使用Quartz. 最近,我一直在研究要在云中部署的JBoss 7.1.1上运行的JEE 6应 ...
- HOW-TO:带有MySQL的JEE应用程序中具有集群功能的Quartz Scheduler
Quartz Scheduler是Java世界中最流行的调度库之一. 过去,我主要在Spring应用程序中使用Quartz. 最近,我一直在研究将在云中部署的JBoss 7.1.1上运行的JEE 6应 ...
- Spring整合Quartz定时任务 在集群、分布式系统中的应用(Mysql数据库环境)
转载:http://www.cnblogs.com/jiafuwei/p/6145280.html 单个Quartz实例能给予你很好的Job调度能力,但它不能满足典型的企业需求,如可伸缩性.高可靠性满 ...
- quarts集群 运维_精讲Elastic-job + Quartz实现企业级定时任务
掌握分布式集群方式的定时任务框架,可以弥补企业中常用的单点任务的缺点,以更高的性能更好的稳定性处理分布式定时任务服务:本课程带你掌握分布式框架Elastic-Job和Quartz,在以多种方式开发定时 ...
最新文章
- string函数_C++[06] string成员函数之删除函数erase
- 【牛客 - 1080D】tokitsukaze and Event(最短路,思维)
- 还在为python远程控制电脑感到苦难?微信库:itchat带你一展风采
- mysql表空间增长过快_Oracle表空间增长异常解决又一例
- php imagemagick安装,在CentOS上为PHP安装Imagick和ImageMagick
- 20145228《网络对抗》 后门原理与实践
- android 工具 lve,Android Studio 4.0 新功能中的Live Layout Inspector详解
- 李开复:中国创业有四大优势
- 看李佩甫的长篇小说《生命册》的感悟
- 通过微信公众号实现H5音频自动播放
- 中电智谷济南高铁西站新能源汽车充电站顺利开工
- 百度收购91无线,效果未必如愿
- 微电子封装技术的发展趋势
- 国外量化平台-quantopian体验
- pycharm配置python2.7.6环境_pycharm如何配置python环境
- 英文有声读物网站(转贴)
- C++第一天(编写第一个程序,变量与常量)
- node.js测试html tdd,nodejs的单元测试框架mocha
- java中doc文件转为pdf文件_java将doc文件转换为pdf文件的三种方法
- java socket 通信协议_java 基于TCP协议的Socket编程和通信