记一次Quartz定时任务导致的系统崩溃Debug过程

在Spring+Hibernate项目中,由于Tomcat reloadable设置为true,更新后一小时系统崩溃。通过catalina.out日志发现,Quartz定时任务在系统关闭时未停止,可能引发内存泄漏。解决方案是在web.xml中配置QuartzContextListener,在ContextDestroyed时调用SchedulerFactoryBean的shutdown方法,确保定时任务在系统关闭时正确停止。
摘要由CSDN通过智能技术生成
公司一个Spring+Hibernate架构的后台管理项目部署到远程服务器的tomcat上,tomcat里reloadable设置为true。

某次更新,将项目class文件替换后,系统自动reload,正常运行。大概一小时后,有人反映说系统无法访问了。后台一查,tomcat已经停止服务了。

查询log日志,未见相关报错。遂找到catalina.out文件,发现系统在重启时有十来条类似如下所示的警告信息:
The web application [/project] appears to have started a thread named [SchedulerFactoryBean-Worker-1] but has faild to stop it. This is very likely to create a memory leak。大意就是某个线程在系统关闭的时候没有被停止掉,可能导致内存泄漏。

看到SchedulerFactoryBean,了解到问题应该出在Quartz定时调度上面。网上查询相关资料,得出出现此问题的原因大概是:系统在关闭时没有给Quartz时间来停止它所创建的定时任务,导致线程未被停止系统便已经关闭了。

解法如下:配置QuartzContextListener实现ServletContextListener,并在ContextDestroyed时执行SchedulerFactoryBean的shutdown方法。以下是代码:

(别忘了在web.xml里面配置上QuartzContextListener哦)


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;

public class QuartzContextListener implements ServletContextListener{

@Override
public void contextDestroyed(ServletContextEvent arg0) {
WebApplicationContext webApplicationContext = (WebApplicationContext) arg0
.getServletContext()
.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
org.quartz.impl.StdScheduler schedulerFactoryBean = (org.quartz.impl.StdScheduler) webApplicationContext
.getBean("schedulerFactoryBean");//配置文件里配置的quartz的beanId
if(schedulerFactoryBean != null) {
schedulerFactoryBean.shutdown();
}
try {
Thread.sleep(5000);//主线程暂停一定时间让quartz schedular执行shutdown
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Override
public void contextInitialized(ServletContextEvent arg0) {
Logger logger = LoggerFactory.getLogger(getClass());
logger.info("QuartzContextListener is initializing");
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值