Подтвердить что ты не робот

Томкат не останавливается. Как я могу отладить это?

У меня есть Tomcat 7, работающий в Linux, который я запускаю через $CATALINA_HOME/bin/startup.sh и завершение работы через $CATALINA_HOME/bin/shutdown.sh
от /etc/init.d

Все в порядке, кроме 1 проблемы. Иногда tomcat не останавливается.
Хотя я останавливаю его, и я вижу в журналах catalina.out, которые идут вниз, если я делаю ps -ef, я все еще вижу, что процесс работает.

В чем может быть проблема? Как я могу отладить это? Я чувствую, что это связано с потоками.

Таким образом, части, которые являются подозрительными, следующие:
1) Я использую Log4j LogManager, чтобы определить, была ли изменена конфигурация log4j, но я делаю Log4jManager.shutdown на contextDestroyed ServletContextListener
2) Я использую базу данных H2, и я вижу при выключении:

SEVERE: веб-приложение [/MyApplication], похоже, запустило thread с именем [H2 Log Writer MYAPPLICATION], но не смог остановить его.
Вероятно, это приведет к утечке памяти.

SEVERE: веб-приложение [/MyApplication], похоже, запустило поток с именем [H2 File Lock Watchdog
/opt/myOrg/tomcat/webapps/MyApplication/db/myDatabase.lock.db], но имеет не удалось остановить его. Вероятно, это приведет к утечке памяти. Апр. 2,
2012 9:08:08 AM org.apache.catalina.loader.WebappClassLoader
clearReferencesThreads SEVERE: веб-приложение [/MyApplication]
похоже, запустил нить с именем [FileWatchdog], но не сработал
чтобы остановить его. Вероятно, это приведет к утечке памяти.

Любая помощь, пожалуйста? Как я могу обнаружить проблему здесь?

UPDATE:
Я сделал kill -3, как было предложено @daveb, и в катализе. Я вижу:

JVMDUMP006I Обработка дампа события "пользователь", подробно "- пожалуйста, подождите. JVMDUMP032I JVM запросил Java-дамп, используя '/etc/init.d/javacore.20120402.093922.2568.0001.txt' в ответ на событие JVMDUMP010I Java дамп, написанное на /etc/init.d/javacore.20120402.093922.2568.0001.txt JVMDUMP013I Обработано событие" дамп "дампа, деталь" ".

В /etc/init.d есть javacore, но я не знаю, как его обрабатывать. То есть какие части я должен исследовать

4b9b3361

Ответ 1

Если веб-приложение остановлено, все соединения с базой данных также должны быть закрыты. Если у вас нет списка подключений, выполните инструкцию SQL shutdown (это работает только для баз данных H2 и HSQLDB).

Если у вас есть зарегистрированный сервлет, вы можете сделать это в методе Servlet.destroy().

Если вы зарегистрировали ServletContextListener, вы можете выполнить оператор "shutdown" в методе ServletContextListener.contextDestroyed(ServletContextEvent servletContextEvent). Это то, что делает org.h2.server.web.DbStarter ServletContextListener (тот, который включен в базу данных H2).

Ответ 2

Узнайте, какие потоки все еще запущены (или заблокированы, ожидающие запуска) с помощью jstack или отправки сигнала в процесс:

kill -3 pid

Когда вы это знаете, вы можете сделать все, что заставило их подключиться к уведомлению об отключении, чтобы остановить потоки. Или создайте эти потоки деамонов.

Подробнее об этом см. Этот вопрос о закрытии tomcat.

Если вы не знаете, где были созданы ваши потоки, подумайте о добавлении им имен - исполнители могут использовать поточные фабрики, и вы можете использовать эти фабрики, чтобы установить статус деамона потока, а также назвать его - так что ваш трассировка стека будет более понятной.

Ответ 3

Убедитесь, что в вашем веб-приложении включен какой-либо планировщик, например Quartz.

Если вы не остановите его, поток веб-приложений никогда не заканчивается, пока вы его не убьете

Ответ 4

У меня была такая же проблема. Иногда команда ./shutdown.sh не останавливает процесс tomcat, а процесс java остается в запущенных процессах.

Я решил эту проблему, используя версию Tomcat в репозиториях программного обеспечения Ubuntu, посредством:

sudo apt-get install tomcat7

После установки из диспетчера пакетов и настройки некоторых параметров у меня не было никаких проблем при остановке/запуске Tomcat. Я использовал эту команду для остановки, и она никогда не сработала:

service tomcat7 stop

что почти совпадает с

/etc/init.d/tomcat7 stop

С помощью этой команды выполняется блок кода из init script, в частности, коды из файла /etc/init.d/tomcat7. Поэтому я посмотрел на него, чтобы увидеть, что он делает, чтобы успешно убить процесс tomcat. Вот код, который выполняется, когда вы используете команду service tomcat7 stop:

log_daemon_msg "Stopping $DESC" "$NAME"

        set +e
        if [ -f "$CATALINA_PID" ]; then
                start-stop-daemon --stop --pidfile "$CATALINA_PID" \
                        --user "$TOMCAT7_USER" \
                        --retry=TERM/20/KILL/5 >/dev/null
                if [ $? -eq 1 ]; then
                        log_progress_msg "$DESC is not running but pid file exists, cleaning up"
                elif [ $? -eq 3 ]; then
                        PID="`cat $CATALINA_PID`"
                        log_failure_msg "Failed to stop $NAME (pid $PID)"
                        exit 1
                fi
                rm -f "$CATALINA_PID"
                rm -rf "$JVM_TMP"
        else
                log_progress_msg "(not running)"
        fi
        log_end_msg 0
        set -e
        ;;

Важная часть:

start-stop-daemon --stop --pidfile "$CATALINA_PID" \
                            --user "$TOMCAT7_USER" \
                            --retry=TERM/20/KILL/5 >/dev/null

Это означает, что "повторная попытка останавливается до тех пор, пока процесс не будет остановлен. Вот документация команды --retry из руководства start-stop-daemon:

   -R|--retry timeout|schedule
          With  --stop,  specifies  that  start-stop-daemon  is  to  check
          whether  the  process(es)  do  finish.  It will check repeatedly
          whether any matching processes are running, until none are.   If
          the  processes  do  not exit it will then take further action as
          determined by the schedule.

          If timeout is specified instead of schedule  then  the  schedule
          signal/timeout/KILL/timeout  is used, where signal is the signal
          specified with --signal.
          ...

Итак, --retry=TERM/20/KILL/5 означает "Отправить TERM сигнал к процессу, подождите 20 секунд, если он все еще работает, отправьте сигнал KILL, подождите 5 секунд, если он все еще работает, есть проблема.

Это означает, что вы можете настроить tomcat для запуска в качестве deamon и использовать такую ​​команду или написать script для выполнения такого действия, чтобы остановить tomcat, или просто использовать Ubuntu и получить tomcat из диспетчера пакетов.

Ответ 5

В моем случае у меня был один мошенник JPA EntityManager, который не был должным образом закрыт после использования. Исправлено это, и теперь я могу чистить и строить снова, не убивая каждый проклятый процесс Java:)

Ответ 6

У меня также была та же проблема. В моем приложении был ThrottledThreadPoolExecutor, который не запускался. Когда я закрою его правильно, tomcat остановится чисто. Чтобы выяснить проблему, мне пришлось удалить все приложения из моего каталога tomcat webapps, а затем добавить их один за другим и посмотреть, какая из них вызывает проблему.

Ответ 7

Если вы используете Планировщик или какой-либо другой объект в своем веб-приложении, вам нужно его отключить. Как правило, вы должны использовать ServletContextListener, чтобы предоставить вам вызов для выключения. В этом случае крюк отключения не будет работать, потому что JVM не закрывается (пока). Поверь мне, я попробовал. Если ваш код находится в коде агента или что-то вне контейнера /webapp, то задержите крючок СЛЕДУЕТ работать, хотя часто это притягивает опыт, чтобы понять, почему он ВСЕ НЕ РАБОТАЕТ. Заметьте, я лысый.