web-dev-qa-db-ja.com

Tomcatは停止しません。どうすればこれをデバッグできますか?

LinuxでTomcat 7を実行していますが、$CATALINA_HOME/bin/startup.shで起動し、$CATALINA_HOME/bin/shutdown.shでシャットダウンします
from /etc/init.d

1つの問題を除き、すべて問題ありません。 Tomcatが停止しない場合があります。
それを停止し、catalina.outログにダウンしているのが表示されますが、ps -efを実行すると、プロセスの実行を確認できます。

何が問題なのでしょうか?どうすればこれをデバッグできますか?私の考えでは、これはスレッドに関連しているということです。

したがって、疑わしい部分は次のとおりです。
1)Log4jのLogManagerを使用してlog4j構成が変更されたかどうかを検出しますが、contextDestroyedServletContextListenerLog4jManager.shutdownを実行します
2)H2データベースを使用し、シャットダウン時に表示されます:

重大:Webアプリケーション[/ MyApplication]が開始したようです
[H2 Log Writer MYAPPLICATION]という名前のスレッドが停止に失敗しました。
これはメモリリークを引き起こす可能性が非常に高い

重大:Webアプリケーション[/ MyApplication]が開始したようです
[H2 File Lock Watchdogという名前のスレッド
/opt/myOrg/Tomcat/webapps/MyApplication/db/myDatabase.lock.db]が
それを停止できませんでした。これにより、メモリリークが発生する可能性が非常に高くなります。 4月2日
2012 9:08:08 AM org.Apache.catalina.loader.WebappClassLoader
clearReferencesThreads SEVERE:Webアプリケーション[/ MyApplication]
[FileWatchdog]という名前のスレッドを開始したようですが、失敗しました
停止します。これにより、メモリリークが発生する可能性が非常に高くなります。

助けてください?ここで問題を検出するにはどうすればよいですか?

更新:
@ davebが示唆するようにkill -3を実行しました。

JVMDUMP006Iダンプイベント「user」、詳細「」を処理しています-お待ちください。 JVMDUMP032I JVMは、イベントJVMDUMP010I Javaに書き込まれたダンプに '/etc/init.d/javacore.20120402.093922.2568.0001.txt'を使用してダンプを要求しましたJava /etc/init.d/javacore.20120402.093922.2568.0001.txt JVMDUMP013Iダンプイベント「user」、詳細「」を処理しました。

/etc/init.dにはjavacoreがありますが、それを処理する方法がわかりません。つまりどの部分を調査すべきですか

32
Jim

Webアプリケーションが停止している場合は、データベースへのすべての接続も閉じる必要があります。接続のリストがない場合は、SQLステートメント「shutdown」を実行します(これはH2およびHSQLDBデータベースでのみ機能します)。

サーブレットを登録している場合は、Servlet.destroy()メソッドでそれを行うことができます。

ServletContextListenerを登録している場合は、ServletContextListener.contextDestroyed(ServletContextEvent servletContextEvent)メソッドで「shutdown」ステートメントを実行できます。これは何 org.h2.server.web.DbStarterServletContextListenerは(H2データベースに含まれているもの)します。

4
Thomas Mueller

Jstackを使用するか、プロセスにシグナルを送信して、まだ実行中の(またはブロックされ、実行を待機している)スレッドを確認します。

kill -3 pid

これを知っていれば、それらを開始したものは何でも、シャットダウン通知にフックしてスレッドを停止することができます。または、それらのスレッドをスレッドのデーモンにします。

詳細については、 このTomcatシャットダウンの質問 を参照してください。

スレッドの作成場所がわからない場合は、スレッドに名前を追加することを検討してください。エグゼキュータはスレッドファクトリを取得でき、これらのファクトリを使用してスレッドのデーモンステータスを設定し、名前を付けることができます。より明確に。

19
daveb

Webアプリケーションで、Quartzなどのアクティブなスケジューラがあるかどうかを確認します。

停止しないと、Webアプリケーションスレッドは終了するまで終了しません。

7
Marco

私はまったく同じ問題を抱えていました。時々、コマンド./shutdown.shはTomcatプロセスを停止せず、そのJavaプロセスは実行中のプロセスにとどまります。

UbuntuのソフトウェアリポジトリにあるTomcatバージョンを使用して、次の方法でこの問題を解決しました。

Sudo apt-get install Tomcat7

パッケージマネージャーからインストールし、いくつかの設定を構成した後、Tomcatの停止/起動に関する問題はありませんでした。このコマンドを使用して停止しましたが、失敗することはありませんでした。

service Tomcat7 stop

これはほぼ同じです

/etc/init.d/Tomcat7 stop

このコマンドを使用すると、initスクリプトのコードブロック、具体的にはファイル/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

つまり、「プロセスが停止するまで停止を再試行します。start-stop-daemon manualの--retryコマンドのドキュメントは次のとおりです。

   -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を構成するか、Tomcatを停止するそのようなアクションを実行するスクリプトを記述するか、Ubuntuを使用してパッケージマネージャーからTomcatを取得することを意味します。

6
Utku Özdemir

私の場合、使用後に適切に閉じられなかった不正なJPA EntityManagerが1つありました。それを修正し、今度はいまいましいJavaプロセスを毎回実行せずに:)

1
JohannSig

私も同じ問題を抱えていました。アプリケーションにThrottledThreadPoolExecutorがシャットダウンしていませんでした。適切にシャットダウンすると、Tomcatは正常に停止します。問題を理解するために、Tomcat webappsディレクトリからすべてのアプリを削除し、それらを1つずつ追加して、問題の原因となっているアプリを確認する必要がありました。

0
Denorm

Webアプリでスケジューラまたはその他のエンティティを使用している場合は、シャットダウンする必要があります。通常、シャットダウン呼び出しを行うためのフックを提供するには、ServletContextListenerを使用する必要があります。この場合、JVMが(まだ)シャットダウンしていないため、シャットダウンフックは機能しません。私を信じて、私は試しました。コードがエージェントコードまたはcontainer/webappの外部にある場合は、シャットダウンフックが機能する必要がありますが、多くの場合、それがまだ機能しない理由を理解するのは非常に困難です。注、私ははげています。

0
ticktock