日期:2014-05-20  浏览次数:20654 次

quartz定时任务不执行的问题
我的是一个用quartz做的定时任务动态管理的项目
现在遇到一个问题是多个定时任务同时进行的时候,某些任务会在某次执行的时间点漏掉(查看日志没有任何报错信息,但是该次任务没有执行)



如上图:第一个任务为每15分钟执行一次,执行时间点为每小时的[0,15,30,45];第二个为每是10分钟一次,时间点为[0,10,20,30,40,50];每个任务又是开启多线程来执行;
每个任务执行一次所用时间大概为2分钟,查看结果发现有漏掉的情况:譬如15分钟的任务某一小时内只在[0,30,45]刻钟执行了,漏掉了第15分钟
以下是关于quartz的配置情况
1.quartz.properties
#============================================================================   
# Configure Main Scheduler Properties     
#============================================================================   
    
org.quartz.scheduler.instanceName = atpScheduler  
org.quartz.scheduler.instanceId = AUTO  
   
#============================================================================   
# Configure ThreadPool     
#============================================================================   
    
orgorg.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool   
org.quartz.threadPool.threadCount = 50  
org.quartz.threadPool.threadPriority = 9  
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = false  
#============================================================================   
# Configure JobStore     
#============================================================================   
#set misfire time to 3 mine    
org.quartz.jobStore.misfireThreshold = 180000
       
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX    
org.quartz.jobStore.tablePrefix = qrtz_ 
org.quartz.jobStore.isClustered = false  
    
#============================================================================   
# 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


2.spring的applicationContext.xml:
<!--初始化SchedulerFactoryBean  -->
<bean name="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" destroy-method="destroy" lazy-init="false">
<property name="dataSource" ref="dataSource"/>
<!--延迟5秒启动  -->
<property name="startupDelay" value="5" /> 
<property name="applicationContextSchedulerContextKey" value="atp-Scheduler" />
<property name="configLocation" value="classpath:quartz.properties" />
<property name="schedulerContextAsMap">      
            <map>       
                <description>schedulerContextAsMap</description>      
                <entry key="runTaskService" value-ref="runTaskService"/>      
            </map>      
        </property>  
</bean>

3.每次任务执行时就新创建一个线程池运行该任务下的用例,执行完就关闭线程池,JAVA代码如下:
       /**
 * 处理数据
 */
@Override
public void disposeData(List<TestCaseResult> listTcr, String uuid) {

ExecutorService servicePoolThread = Executors.newFixedThreadPool(task.getThread_num());// 创建线程池
try {
for (Thread t : publicThread) {
servicePoolThread.submit(t);
}
servicePoolThread.shutdown();
boolean loop = true;
do { // 等待所有线程结束
loop = !servicePoolThread.awaitTermination(5, TimeUnit.SECONDS);
logger.info(uuid+ "`====== waiting for the end of All threads ======");
} while (loop);
logger.info(uuid+ "`====== shutdown the thread pool,main end ======");
} catch (InterruptedException e) {
servicePoolThread.shutdownNow();
Thread.currentThread().interrupt();
logger.error(uuid+ "`==== error in run periodJob(disposeData) --->"+ e.getMessage());
e.printStackTrace();
}
}


============================================================================================
以上程序有关线程调用的大体情况,在网上查了一些解决方法
(1).有可能web关闭过程中没有正常关闭quartz,导致下次重启后quartz执行有问题
      在监听器中添加了quartz的shutdown方法,
      web.xml增加了内存清理监控org.springframework.web.util.IntrospectorCleanupListener