这篇文章给大家分享的是有关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-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
定时任务配置如下:
<!-- 工作的bean -->
<bean id="myJob" class=" com.gionee.baserom.exchangerate.job.DailyTaskJob" />
<!-- 定义任务,为了避免线程阻塞,用concurrent=false -->
<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">1</prop>
</props>
</property>
<property name="waitForJobsToCompleteOnShutdown">
<value>false</value>
</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);
}
}
}
1、单定时任务之间是串行,之前的任务没执行完,下一个任务不会启动。
2、多个任务之间会相互干扰,其他同一时刻启动的任务没执行完,下一个任务不会启动。
1、首先检查自己的代码,是否有死锁、卡住、bug、http请求没有设置超时时间等问题。
2、检查是否所有定时任务都不启动,如果是基本判断是特性2导致的,检查是哪个定时任务执行慢、卡住、出现bug等情况。
1、修复bug,如果有的话。
2、如果就是有个任务执行慢,无法优化,可以不用spring的定时任务,改用Quartz。
依赖包
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
配置:
<!-- 工作的bean -->
<bean id="myJob" class=" com.gionee.baserom.exchangerate.job.DailyTaskJob" />
<!-- 定义任务,为了避免线程阻塞,用concurrent=false -->
<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">1</prop>
</props>
</property>
<property name="waitForJobsToCompleteOnShutdown">
<value>false</value>
</property>
<property name="triggers">
<list>
<ref bean="myJobTrigger" />
</list>
</property>
</bean>
感谢各位的阅读!关于“Spring定时任务无故停止又不报错怎么办”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。