Spring定時任務無故停止又不報錯的解決
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之后才能繼續(xù)執(zhí)行定時任務。
開始以為由于數(shù)據庫最大連接數(shù)的限制,設置成翻倍了之后仍出現(xiàn)這問題。在同學的提醒下意識到可能是線程阻塞導致,于是網上查到原因:
Spring定時任務默認都是并發(fā)執(zhí)行的,不會等待上一次任務執(zhí)行完畢,只要間隔時間到就會執(zhí)行。
解決方案
1.將JobDetail的concurrent屬性配置為false。不允許任務并發(fā)執(zhí)行。
2.任務執(zhí)行時間較長時,查找根本問題。
于是把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> <!-- 配置觸發(fā)器 --> <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); } } }
Spring定時任務跑完不再啟動
spring的定時任務有以下兩個特性
1、單定時任務之間是串行,之前的任務沒執(zhí)行完,下一個任務不會啟動。
2、多個任務之間會相互干擾,其他同一時刻啟動的任務沒執(zhí)行完,下一個任務不會啟動。
排查方式
1、首先檢查自己的代碼,是否有死鎖、卡住、bug、http請求沒有設置超時時間等問題。
2、檢查是否所有定時任務都不啟動,如果是基本判斷是特性2導致的,檢查是哪個定時任務執(zhí)行慢、卡住、出現(xiàn)bug等情況。
解決思路
1、修復bug,如果有的話。
2、如果就是有個任務執(zhí)行慢,無法優(yōu)化,可以不用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> <!-- 配置觸發(fā)器 --> <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>
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Springboot?引入?Redis?并配置序列化并封裝RedisTemplate?
這篇文章主要介紹了Springboot?引入?Redis?并配置序列化并封裝RedisTemplate。文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09Idea自定義方法注釋模板的教程詳解(去param括號、return全類名)
這篇文章主要介紹了Idea自定義方法注釋模板(去param括號、return全類名),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08使用java實現(xiàn)“釘釘微應用免登進入某H5系統(tǒng)首頁“功能”
這篇文章主要介紹了用java實現(xiàn)“釘釘微應用,免登進入某H5系統(tǒng)首頁“功能”,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-10-10JSP、Servlet中get請求和post請求的區(qū)別總結
這篇文章主要介紹了JSP、Servlet中get請求和post請求的區(qū)別總結,列舉了多條不同點,需要的朋友可以參考下2014-07-07