Spring定时任务无故停止又不报错

一开始是使用Spring自带的定时器来配置定时任务的,简单快捷,配置如下:

<bean id="refreshCache" class="com.gionee.baserom.search.job.RefreshCache" />
<task:scheduled-tasks>
    <task:scheduled ref="refreshCache" method="execute" cron="0 */30 * * * ?"/>
task:scheduled-tasks>

但是使用一段时间之后就无故停止,且不报错,所以没有相关错误日志,需要重启Tomcat之后才能继续执行定时任务。
开始以为由于数据库最大连接数的限制,设置成翻倍了之后仍出现这问题。在同学的提醒下意识到可能是线程阻塞导致,于是网上查到原因:

Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。
解决方案:
1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。
2.任务执行时间较长时,查找根本问题。

于是把Spring自带的定时器改用Quartz,依赖相关包:

<dependency>
        <groupId>org.quartz-schedulergroupId>
        <artifactId>quartzartifactId>
        <version>2.2.1version>
dependency>

定时任务配置如下:


    <bean id="myJob" class=" com.gionee.baserom.exchangerate.job.DailyTaskJob" />

    
    <bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject" ref="myJob" />
        <property name="targetMethod" value="execute" />
        <property name="concurrent" value="false" />
    bean>

    
    <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="myJobDetail" />
        <property name="cronExpression" value="0 0/30 * * * ?" />
    bean>

    
    <bean name="startQuertz" lazy-init="false" autowire="no" destroy-method="destroy" class="com.gionee.baserom.exchangerate.util.SchedulerFactoryBeanWithShutdownDelay" >
        <property name="quartzProperties">
            <props>
                <prop key="org.quartz.threadPool.threadCount">1prop>
            props>
        property>
        <property name="waitForJobsToCompleteOnShutdown">
            <value>falsevalue>
        property>
        <property name="triggers">
            <list>
                <ref bean="myJobTrigger" />
            list>
        property>
    bean>

在startQuartz中用到SchedulerFactoryBeanWithShutdownDelay是因为当Tomcat被关闭时,有可能导致任务线程并未完全关闭,导致内存泄漏。
SchedulerFactoryBeanWithShutdownDelay.java

import org.quartz.SchedulerException;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean {
    @Override  
    public void destroy() throws SchedulerException {  
        super.destroy();  


        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            throw new RuntimeException(e);  
        }  
    }  
}

你可能感兴趣的:(开发经验)