Spring整合Quartz定時任務 在集群、分布式系統中的應用(Mysql數據庫環境)
Spring整合Quartz定時任務 在集群、分布式系統中的應用(Mysql數據庫環境)
轉載:http://www.cnblogs.com/jiafuwei/p/6145280.html
單個Quartz實例能給予你很好的Job調度能力,但它不能滿足典型的企業需求,如可伸縮性、高可靠性滿足。假如你需要故障轉移的能力並能運行日益增多的 Job,Quartz集群勢必成為你應用的一部分了。使用 Quartz 的集群能力可以更好的支持你的業務需求,並且即使是其中一臺機器在最糟的時間崩潰了也能確保所有的 Job 得到執行。
Quartz 中集群如何工作
一個 Quartz 集群中的每個節點是一個獨立的 Quartz 應用,它又管理著其他的節點。意思是你必須對每個節點分別啟動或停止。不像許多應用服務器的集群,獨立的 Quartz 節點並不與另一其的節點或是管理節點通信。Quartz 應用是通過數據庫表來感知到另一應用的。
圖:表示了每個節點直接與數據庫通信,若離開數據庫將對其他節點一無所知
創建Quartz數據庫表
因為Quartz 集群依賴於數據庫,所以必須首先創建Quartz數據庫表。Quartz 包括了所有被支持的數據庫平臺的 SQL 腳本。解壓 Quartz 分發包後的目錄,在 /docs/dbTables 目錄下找到那些 SQL 腳本。
總共11張表,不同版本,表個數可能不同。數據庫為mysql,用tables_mysql_innodb.sql創建數據庫表。
# # In your Quartz properties file, you‘ll need to set # org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate # # # By: Ron Cordell - roncordell # I didn‘t see this anywhere, so I thought I‘d post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM. 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; 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; 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; 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(120) 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; 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; 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), INDEX (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; 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; 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; 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; 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; CREATE TABLE QRTZ_LOCKS ( SCHED_NAME VARCHAR(120) NOT NULL, LOCK_NAME VARCHAR(40) NOT NULL, PRIMARY KEY (SCHED_NAME,LOCK_NAME)) ENGINE=InnoDB; CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); commit;
配置 Quartz 使用集群
1.配置節點的 quartz.properties 文件
#============================================================== #Configure Main Scheduler Properties #============================================================== org.quartz.scheduler.instanceName = defaultScheduler 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.dataSource = myDS org.quartz.jobStore.maxMisfiresToHandleAtATime = 1 org.quartz.jobStore.misfireThreshold = 120000 org.quartz.jobStore.txIsolationLevelSerializable = true #============================================================== #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
org.quartz.scheduler.instanceName 屬性可為任何值,用在 JDBC JobStore 中來唯一標識實例,但是所有集群節點中必須相同。
org.quartz.scheduler.instanceId 屬性為 AUTO即可,基於主機名和時間戳來產生實例 ID。
org.quartz.jobStore.class 屬性為 JobStoreTX,將任務持久化到數據中。因為集群中節點依賴於數據庫來傳播 Scheduler 實例的狀態,你只能在使用 JDBC JobStore 時應用 Quartz 集群。這意味著你必須使用 JobStoreTX 或是 JobStoreCMT 作為 Job 存儲;你不能在集群中使用 RAMJobStore。
org.quartz.jobStore.isClustered 屬性為 true,你就告訴了 Scheduler 實例要它參與到一個集群當中。這一屬性會貫穿於調度框架的始終,用於修改集群環境中操作的默認行為。
org.quartz.jobStore.clusterCheckinInterval 屬性定義了Scheduler 實例檢入到數據庫中的頻率(單位:毫秒)。Scheduler 檢查是否其他的實例到了它們應當檢入的時候未檢入;這能指出一個失敗的 Scheduler 實例,且當前 Scheduler 會以此來接管任何執行失敗並可恢復的 Job。通過檢入操作,Scheduler 也會更新自身的狀態記錄。clusterChedkinInterval 越小,Scheduler 節點檢查失敗的 Scheduler 實例就越頻繁。默認值是 15000 (即15 秒)。
2.配置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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="myJobFactory" class="com.xiyinli.Timed.MyJobFactory"></bean> <bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobFactory" ref="myJobFactory"/> <property name="dataSource" ref="dataSource"/> <property name="applicationContextSchedulerContextKey" value="applicationContextKey" /> <property name="configLocation" value="classpath:quartz.properties" /> <property name="triggers"> <list> <ref bean="orderTimedTrigger" /> <ref bean="bonusTimedTrigger" /> <ref bean="cltWeightedCommissionTimedTrigger" /> <ref bean="emptyVisitOfTodayTimedTrigger" /> <ref bean="userCentCommissionTimedTrigger" /> </list> </property> </bean> <!-- quartz1 --> <bean id="orderTimedClass" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass"> <value>com.xiyinli.Timed.OrderTimed</value> </property> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="orderTimedTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="orderTimedClass" /> <property name="cronExpression" value="0 0/5 * * * ?" /> <!-- //每5分鐘執行一次 --> </bean> <!-- quartz2 --> <bean id="bonusTimedClass" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass"> <value>com.xiyinli.Timed.BonusTimed</value> </property> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="bonusTimedTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="bonusTimedClass" /> <property name="cronExpression" value="0 05 00 1 * ?" /> <!-- //每月一號00:05分執行一次 --> </bean> <!-- quartz3 --> <bean id="cltWeightedCommissionTimedClass" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass"> <value>com.xiyinli.Timed.CltWeightedCommissionTimed</value> </property> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="cltWeightedCommissionTimedTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="cltWeightedCommissionTimedClass" /> <property name="cronExpression" value="0 0 1 * * ?" /> <!-- //"0 0 1 * * ?" 每天1點,統計上一天的營業額 --> </bean> <!-- quartz4 --> <bean id="emptyVisitOfTodayTimedClass" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass"> <value>com.xiyinli.Timed.EmptyVisitOfTodayTimed</value> </property> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="emptyVisitOfTodayTimedTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="emptyVisitOfTodayTimedClass" /> <property name="cronExpression" value="0 10 0 * * ?" /> <!-- ///每天00:10點,統計上一天的營業額 --> </bean> <!-- quartz5 --> <bean id="userCentCommissionTimedClass" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass"> <value>com.xiyinli.Timed.UserCentCommissionTimed</value> </property> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="userCentCommissionTimedTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="userCentCommissionTimedClass" /> <property name="cronExpression" value="0 0 3 * * ?" /> <!-- //0 0 3 * * ? 每天淩晨3點 分傭解凍 --> </bean> </beans>
dataSource:項目中用到的數據源,裏面包含了quartz用到的11張數據庫表;
applicationContextSchedulerContextKey: 是org.springframework.scheduling.quartz.SchedulerFactoryBean這個類中把spring上下 文以key/value的方式存放在了SchedulerContext中了,可以用applicationContextSchedulerContextKey所 定義的key得到對應spring 的ApplicationContext;
configLocation:用於指明quartz的配置文件的位置
requestsRecovery
requestsRecovery屬性必須設置為 true,當Quartz服務被中止後,再次啟動或集群中其他機器接手任務時會嘗試恢復執行之前未完成的所有任務。
<bean id="myJobFactory" class="com.xiyinli.Timed.MyJobFactory"></bean>為重寫的bean管理工廠類方便定時類service註入bean:
package com.xiyinli.Timed; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; /** * Created by Administrator on 2017/8/16 0016. */ public class MyJobFactory extends AdaptableJobFactory { //這個對象Spring會幫我們自動註入進來,也屬於Spring技術範疇. @Autowired private AutowireCapableBeanFactory capableBeanFactory; protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //調用父類的方法 Object jobInstance = super.createJobInstance(bundle); //進行註入,這屬於Spring的技術,不清楚的可以查看Spring的API. capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
3.把applicationContext-quartz.xml引入spring, applicationContext-quartz.xml中的dataSource為上面spring-mybatis.xml的bean數據庫配置
4. 上面的配置是多任務多定時器,這裏以其中的 com.xiyinli.Timed.EmptyVisitOfTodayTimed 為例,其他4個一樣編寫。
package com.xiyinli.Timed; import com.xiyinli.mapper.StoreMapper; import com.xiyinli.service.StoreService; import org.apache.log4j.Logger; import org.quartz.DisallowConcurrentExecution; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.PersistJobDataAfterExecution; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; /** * Created by Administrator on 2017/8/2. */ @Service @Transactional @PersistJobDataAfterExecution @DisallowConcurrentExecution// 不允許並發執行 public class EmptyVisitOfTodayTimed extends QuartzJobBean { private Logger log = Logger.getLogger(this.getClass()); private static boolean isRun = false; @Autowired private StoreMapper storeMapper; @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { if (isRun) { log.debug("EmptyVisitOfTodayTimed-前一次未執行完,跳過本次任務!"); return; } isRun = true; commissionTask(); isRun = false; log.debug("執行邏輯-EmptyVisitOfTodayTimed-isRunFinish"); } //------------------------------------------------------------------------------------------------------------------ public void commissionTask() { log.debug("淩晨00:10清空每日訪問量"); Boolean b = storeMapper.updateTodayVisit(); if (b){ log.debug("正常清空"); }else{ log.debug("清空失敗"); } log.debug("清空每日訪問量執行結束"); } }
5.在最後測試時發現,windows環境運行正常,不是到linux環境下啟動時會出現如下錯誤:
ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘quartzScheduler‘ defined ...
Caused by: Java.lang.IllegalStateException: Cannot run without an instance id.
可以嘗試使用下面的辦法進行解決(一般情況是不能識別主機名):
先查找主機名復制下來:
[root@iZbp12b0psb88pmxixiwcsZ /]# hostname iZbp12b0psb88pmxixiwcsZ
然後:
[root@iZbp12b0psb88pmxixiwcsZ /]# vi /etc/hosts
編輯如下即可:
轉載:http://www.cnblogs.com/007sx/p/7374095.html
http://www.cnblogs.com/jiafuwei/p/6145280.html
Spring—Quartz定時調度CronTrigger時間配置格式說明與實例 http://blog.csdn.net/foamflower/article/details/4260645
Spring整合Quartz定時任務 在集群、分布式系統中的應用(Mysql數據庫環境)