【问题标题】:Handling Tomcat shutdown gracefully when using quartz and struts framework使用quartz和struts框架时优雅地处理Tomcat关闭
【发布时间】:2011-03-04 02:13:10
【问题描述】:

我正在使用 struts 和石英框架来安排工作。它工作正常。

但是当我停止 Tomcat(6.0.26) 时,它会在控制台上抛出错误,如

“Web 应用程序似乎启动了一个名为 [.....] 的线程,但未能停止它。这很可能导致内存泄漏。

任何人都知道如何优雅地处理这个......

目前我的 struts config.xml 看起来像这样: <plug-in className="com.example.scheduler.SchedulerPlugin"> <set-property property="startOnLoad" value="true"/> <set-property property="startupDelay" value="0"/> </plug-in>

【问题讨论】:

    标签: tomcat struts quartz-scheduler


    【解决方案1】:

    确定的最好方法是发送一个 SIGQUIT (kill -3) 程序并分析输出以查看哪个线程仍在运行。

    很可能您的作业(在其中一个 Quartz 线程之上运行)没有对关闭信号做出反应并继续工作。对于耗时较长的工作,您可以定期查看jobExecutionContext.getScheduler().isShutdown() 或将您的工作编程为InterruptableJob 并正确响应中断。

    【讨论】:

      【解决方案2】:

      您需要调用 scheduler.shutdown(true) 来告诉 Quartz 等待任何正在进行的作业完成执行。

      另外,一些 tomcat 用户报告说,他们还需要在关闭调用后暂停线程一秒钟左右,以便在 tomcat 尝试检测线程是否仍在运行之前让其他线程有时间清理 CPU。

      在此处查看讨论:http://forums.terracotta.org/forums/posts/list/3479.page

      【讨论】:

        【解决方案3】:

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

        具体来说,你需要在你的 web.xml 中添加一个 ServletContextListener:

        <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 线程,但这些是不同的问题)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-02
          • 2010-09-13
          相关资源
          最近更新 更多