使用quartz和struts框架时优雅地处理Tomcat关闭

发布于 2024-10-20 09:03:57 字数 432 浏览 6 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蔚蓝源自深海 2024-10-27 09:03:57

确定的最佳方法是发送 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 become InterruptableJob and properly respond to interruptions.

痴情换悲伤 2024-10-27 09:03:57

您需要调用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

不回头走下去 2024-10-27 09:03:57

这是 jhouse 答案的扩展。我不能将此代码放在注释中:-(。

具体来说,您需要将 ServletContextListener 添加到您的 web.xml 中:

<listener>
    <listener-class>org.whatever.MyListener</listener-class>
</listener>

然后在实现中,在上下文 contextDestroyed() 方法中,睡眠 10 秒(1 秒是'对于我的应用程序来说还不够)。它应该看起来像这样:

public class MyListener implements ServletContextListener {


    public void contextInitialized(ServletContextEvent arg0) {}

    /**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0) {
        try {
            // This can't use logging because it's (hopefully) been shut down by now.
            System.out.println("Sleep for a bit so that we don't get any errors about Quartz threads not being shut down yet. ");
            // For more info, see here: http://stackoverflow.com/questions/2730354/spring-scheduler-shutdown-error
            Thread.sleep(10 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我不需要调用调度程序关闭方法(很明显它们已经在某个地方被调用了,也许因为我正在使用 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:

<listener>
    <listener-class>org.whatever.MyListener</listener-class>
</listener>

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:

public class MyListener implements ServletContextListener {


    public void contextInitialized(ServletContextEvent arg0) {}

    /**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0) {
        try {
            // This can't use logging because it's (hopefully) been shut down by now.
            System.out.println("Sleep for a bit so that we don't get any errors about Quartz threads not being shut down yet. ");
            // For more info, see here: http://stackoverflow.com/questions/2730354/spring-scheduler-shutdown-error
            Thread.sleep(10 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文