使用quartz和struts框架时优雅地处理Tomcat关闭
我正在使用 struts 和quartz 框架来安排工作。效果很好。
但是当我停止 Tomcat(6.0.26) 时,它会在控制台上抛出错误,例如
“Web 应用程序似乎已经启动了一个名为 [.....] 的线程,但未能停止它。这很可能会导致内存泄漏。
任何人都知道如何优雅地处理这个问题...
目前我的 struts config.xml 如下所示: <插件类名=“com.example.scheduler.SchedulerPlugin”>
I am using struts and quartz framework to schedule a job. It works fine.
But When I stop Tomcat(6.0.26), it throws out error on the console like
"The web application appears to have started a thread named[.....] but has failed to stop it. This is very likely to cause a memory leak.
Anyone knows how to handle this gracefully...
Currently my struts config.xml looks like this:<plug-in className="com.example.scheduler.SchedulerPlugin">
<set-property property="startOnLoad" value="true"/>
<set-property property="startupDelay" value="0"/>
</plug-in>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确定的最佳方法是发送 SIGQUIT (kill -3) 程序并分析输出以查看哪个线程仍在运行。
您的作业(在 Quartz 线程之一上运行)很可能没有对关闭信号做出反应并继续工作。对于耗时较长的作业,您可以定期检查
jobExecutionContext.getScheduler().isShutdown()
或将作业编程为InterruptableJob
并正确响应中断。The best way to know for sure is to send a SIGQUIT (kill -3) program and analyze the output to see which thread is still running.
It is very likely that your job (which runs on top of one of Quartz threads) did not react to a shutdown signal and continued to work. For long-time-taking jobs, you can check
jobExecutionContext.getScheduler().isShutdown()
periodically or program your job to becomeInterruptableJob
and properly respond to interruptions.您需要调用scheduler.shutdown(true)来告诉Quartz等待任何正在进行的作业完成执行。
此外,一些 tomcat 用户报告说,他们还需要在关闭调用后暂停线程一秒钟左右,以便在 tomcat 尝试检测线程是否仍在运行之前允许其他线程 cpu 有时间进行清理。
请参阅此处的讨论:http://forums.terracotta.org/forums/posts/list /3479.page
You need to call scheduler.shutdown(true) to tell Quartz to wait for any in-progress jobs to finish executing.
Also, some tomcat users have reported that they also need to pause the thread for a second or so after the shutdown call to allow the other threads cpu time to cleanup before tomcat tries to detect whether threads were left running.
See discussion here: http://forums.terracotta.org/forums/posts/list/3479.page
这是 jhouse 答案的扩展。我不能将此代码放在注释中:-(。
具体来说,您需要将 ServletContextListener 添加到您的 web.xml 中:
然后在实现中,在上下文 contextDestroyed() 方法中,睡眠 10 秒(1 秒是'对于我的应用程序来说还不够)。它应该看起来像这样:
我不需要调用调度程序关闭方法(很明显它们已经在某个地方被调用了,也许因为我正在使用 Spring)。添加等待,然后它们都消失了(除了 FileWatchdog Log4j 线程和其他一些 MySQL 线程,但这些是不同的问题)。
This is an expansion on jhouse's answer. I can't put this code in a comment :-(.
Specifically, you need to add a ServletContextListener to your web.xml:
Then in the implementation, in the context contextDestroyed() method, sleep for 10 seconds (1 second wasn't enough for my app). It should look something like this:
I had no need for calling the scheduler shutdown methods (it was clear they were already being called somewhere, maybe 'cuz I'm using Spring). All I needed to do was add the wait and then they all went away (except a FileWatchdog Log4j thread and some other MySQL thread, but those are different questions).