Прекрасно справляется с отключением Tomcat при использовании каркаса из кварца и распорок - PullRequest
3 голосов
/ 04 марта 2011

Я использую распорки и кварцевый каркас для планирования работы.Он работает нормально.

Но когда я останавливаю Tomcat (6.0.26), он выдает ошибку на консоли, как

"Кажется, веб-приложение запустило поток с именем [.....] но не смог остановить его. Это очень вероятно, что может привести к утечке памяти.

Кто-нибудь знает, как с этим справиться ...

В настоящее время мой Struts config.xml выглядит такэто: <plug-in className="com.example.scheduler.SchedulerPlugin"> <set-property property="startOnLoad" value="true"/> <set-property property="startupDelay" value="0"/> </plug-in>

Ответы [ 3 ]

5 голосов
/ 05 марта 2011

Лучший способ узнать наверняка - отправить программу SIGQUIT (kill -3) и проанализировать вывод, чтобы увидеть, какой поток все еще работает.

Весьма вероятно, что ваша работа (которая выполняется поверх одного из кварцевых потоков) не реагировала на сигнал выключения и продолжала работать. Для длительных работ вы можете периодически проверять jobExecutionContext.getScheduler().isShutdown() или программировать свою работу на InterruptableJob и правильно реагировать на прерывания.

4 голосов
/ 05 марта 2011

Вам нужно вызвать scheduler.shutdown (true), чтобы сказать Quartz, чтобы он ожидал завершения выполняемых заданий.

Кроме того, некоторые пользователи tomcat сообщают, что им также необходимо приостановить поток на секунду или около того после вызова выключения, чтобы позволить процессору времени других потоков произвести очистку, прежде чем tomcat попытается определить, остались ли потоки работающими.

Смотрите обсуждение здесь: http://forums.terracotta.org/forums/posts/list/3479.page

3 голосов
/ 17 июня 2014

Это расширение ответа jhouse.Я не могу поместить этот код в комментарий: - (.

В частности, вам нужно добавить ServletContextListener в ваш web.xml:

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

Затем в реализации, вМетод context 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: /1679334/oshibka-vyklycheniya-planirovschika-spring
            Thread.sleep(10 * 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Мне не нужно вызывать методы выключения планировщика (этобыло ясно, что они уже где-то вызывались, может быть, потому что я использую Spring). Все, что мне нужно было сделать, это добавить ожидание, а затем все они ушли (за исключением потока FileWatchdog Log4j и некоторого другого потока MySQL, но они отличаютсявопросы).

...