序文
以前仕事中に書いたブログ投稿の一部がブログに同期されませんでした。この記事は、読者にインスピレーションを与えることを目的として、1 年以上前に書かれた可能性があります。
まずはプロジェクトの背景をご紹介します。私たちのプロジェクトは Tomcat にデプロイされています。1 つの Tomcat の下で複数の Java プロジェクトが実行されています。再デプロイ (war パッケージを webapps ディレクトリに直接スローする) と、プロジェクトが長時間実行されることがよくあります。そして、フォローアップの解決策は次のとおりです。通常は Tomcat を再起動します。
これは私が行ったトラブルシューティングの試みです。
1. まず、Tomcat マネージャー インターフェイスを開きます。
具体的な手順は次のとおりです。
- /tomcat/conf/tomcat-users.xml に以下を追加します。
<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>
- CATALINA_HOME/webapps/manager/META-INF/context.xml、コメントのリモート接続制限:
<Context antiResourceLocking="false" privileged="true" >
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->
</Context
- リモート ホストへのアクセス: 8080 [マネージャー アプリ] をクリックします:
- プロジェクトを再デプロイし、「リークの検索」ボタンをクリックします。
- メモリ リークがあるかどうかを確認します。
2. サーバーのステータスを表示する
メモリのステータスを表示します。
3. JMXの構成
パスワードがありません
- /tomcat/bin/setenv.sh を編集します
#!/bin/sh
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=120.25.205.78 -Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=18889"
#JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management. j mxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access -Dcom.sun.manag em ent.jmxremote.port=18889"
最初のホスト名は IP である必要があり、2 番目に 127.0.0.1 は使用できないことに注意してください。仮想マシンなどの場合は、192.168.1.3 などのイントラネットアドレスを使用できます。クラウドサーバーなどの外部ネットワークアドレスを入力します。
- Tomcatを再起動します。
パスワード付き
- /tomcat/bin/setenv.sh を編集します
#!/bin/sh
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=xxx -Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management. j mxremote.password.file=../conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
-Dcom.sun.management.jmxremote.port=18889"
- /tomcat/conf/jmxremote.password アカウント権限の作成/編集
monitorRole readonly controlRole readwrite
- /tomcat/conf/jmxremote.access アカウントのパスワードを作成/編集します
monitorRole tomcat
controlRole tomcat
- 読み取りおよび書き込み権限を変更します。
chmod 600 jmxremote.access
chmod 600 jmxremote.password
- Tomcatを再起動します
故障解析
Telnet を使用して、ポートが使用可能かどうかを確認できます。使えない場合はファイアウォールなどを見てください。
4. jstatの設定
- 環境変数JAVA_HOMEが存在するか確認してください。それはjdkのインストール方法に関係があります。
export | grep JAVA_HOME
- この変数を表す出力があるため、次のステップでは jstatd.all.policy ファイルを作成します。
mkdir -p /etc/java/
cd /etc/java/
(sudo) vim jstatd.all.policy
- ファイル jstatd.all.policy を編集すると、JAVA_HOME の有無を確認するのはファイルの内容を参照するためであることがわかります。
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
- 起動
jstatd -J-Djava.security.policy=jstatd.all.policy -J Djava.rmi.server.hostname=xxx &
5. Tomcat ログを分析する
質問:
A web application appears to have started a thread named [Abandoned connection cleanup thread] but has failed to stop it. This is very likely to create a memory leak.
解決:
-
mysql-connector-java をアップグレードする
-
導入
@Component public class ShutdownListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { } @Override public void contextDestroyed(ServletContextEvent sce) { AbandonedConnectionCleanupThread.checkedShutdown(); } }
参考:https://bugs.mysql.com/bug.php?id=69526
ホットデプロイメント現象
VisualVM を使用して、メモリ リークのあるプロジェクトを観察してデプロイします。