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構成が変更されたかどうかを検出しますが、contextDestroyed
ServletContextListener
でLog4jManager.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がありますが、それを処理する方法がわかりません。つまりどの部分を調査すべきですか
Webアプリケーションが停止している場合は、データベースへのすべての接続も閉じる必要があります。接続のリストがない場合は、SQLステートメント「shutdown」を実行します(これはH2およびHSQLDBデータベースでのみ機能します)。
サーブレットを登録している場合は、Servlet.destroy()
メソッドでそれを行うことができます。
ServletContextListener
を登録している場合は、ServletContextListener.contextDestroyed(ServletContextEvent servletContextEvent)
メソッドで「shutdown」ステートメントを実行できます。これは何 org.h2.server.web.DbStarter
ServletContextListener
は(H2データベースに含まれているもの)します。
Jstackを使用するか、プロセスにシグナルを送信して、まだ実行中の(またはブロックされ、実行を待機している)スレッドを確認します。
kill -3 pid
これを知っていれば、それらを開始したものは何でも、シャットダウン通知にフックしてスレッドを停止することができます。または、それらのスレッドをスレッドのデーモンにします。
詳細については、 このTomcatシャットダウンの質問 を参照してください。
スレッドの作成場所がわからない場合は、スレッドに名前を追加することを検討してください。エグゼキュータはスレッドファクトリを取得でき、これらのファクトリを使用してスレッドのデーモンステータスを設定し、名前を付けることができます。より明確に。
Webアプリケーションで、Quartzなどのアクティブなスケジューラがあるかどうかを確認します。
停止しないと、Webアプリケーションスレッドは終了するまで終了しません。
私はまったく同じ問題を抱えていました。時々、コマンド./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を取得することを意味します。
私の場合、使用後に適切に閉じられなかった不正なJPA EntityManagerが1つありました。それを修正し、今度はいまいましいJavaプロセスを毎回実行せずに:)
私も同じ問題を抱えていました。アプリケーションにThrottledThreadPoolExecutorがシャットダウンしていませんでした。適切にシャットダウンすると、Tomcatは正常に停止します。問題を理解するために、Tomcat webapps
ディレクトリからすべてのアプリを削除し、それらを1つずつ追加して、問題の原因となっているアプリを確認する必要がありました。
Webアプリでスケジューラまたはその他のエンティティを使用している場合は、シャットダウンする必要があります。通常、シャットダウン呼び出しを行うためのフックを提供するには、ServletContextListenerを使用する必要があります。この場合、JVMが(まだ)シャットダウンしていないため、シャットダウンフックは機能しません。私を信じて、私は試しました。コードがエージェントコードまたはcontainer/webappの外部にある場合は、シャットダウンフックが機能する必要がありますが、多くの場合、それがまだ機能しない理由を理解するのは非常に困難です。注、私ははげています。