javascript
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=1234565、配置 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 = 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
?
#============================================================================
# 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??墒乾F在遇到個問題,放狗都搜不到什么東西。
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)請前輩指點一二,叩謝
?
啊,前輩,剛才那個問題莫名其妙就沒了?,F在是另外一個問題,我的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集群的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SourceTree与git及Andro
- 下一篇: spring-data-jpa原理探秘(