Selbst in der heutigen Zeit gibt es noch viele Webanwendungen, die Tomcat verwenden. (Es ist keine Kritik, es wird in vielen Diensten verwendet, das Versions-Upgrade wird fortgesetzt und es ist ein Produkt mit vielen Informationen, daher denke ich, dass es ein ausgezeichneter Anwendungsserver ist.)
Wenn das Entwicklungsunternehmen die Umgebung erstellt, das in Java integrierte System auf dem Server bereitstellt und es eine Weile betreibt, können unvermeidlich Probleme hinsichtlich der Leistung auftreten.
Zum Beispiel ist es gut, Protokolle auszugeben, aber da Rotations- und Dateizerstörungszyklus nicht berücksichtigt werden, wird der Speicher unter Druck gesetzt, und plötzlich fallen Stein und Server aus, und die Verwendung des Heapspeichers steigt allmählich an. Dann stirbt Tomcat aufgrund von OutOfMemoryError usw., und selbst wenn es nicht stirbt, verschlechtert sich die Systemreaktion und es treten Probleme auf, und verschiedene andere Dinge treten auf.
Wenn Sie feststellen, dass Sie Ihren Speicherplatz belasten, löschen Sie häufig Dateien, die Sie für unnötig und ** vorübergehend ** und ** wieder dauerhaft ** halten.
Wenn die Reaktion des Systems schlecht ist und es den Anschein hat, dass der Speicher nach einer leichten Untersuchung die Ursache ist, starten Sie Tomcat und ** vorläufigen Support ** und ** permanenten Support neu, wenn die geschäftlichen Auswirkungen groß sind, wenn sie nicht sofort behoben werden. Die Ursachenuntersuchung für ** soll so etwas wie "Wenn Sie versuchen, sie in den magischen Worten der Entwicklungsfirma wiederzugeben" sein, werde ich sie zu diesem Zeitpunkt untersuchen ", und" Permanente Korrespondenz "wird nicht für immer kommen .. (Es ist eine persönliche Erfahrung und gilt nicht für die ganze Welt.)
Ich habe lange Zeit so etwas wie ein Murren erwähnt, aber die Analyse der Speichernutzung ist möglicherweise erst bekannt, wenn das eigentliche Problem auftritt, und die Situation ist auch in der Produktionsumgebung und der Entwicklungsumgebung der Entwicklungsfirma. Ich verstehe, dass es schwierig zu reproduzieren ist, weil es anders ist. Die derzeitige Situation besteht darin, dass Wartungsverträge von Anwenderunternehmen nur ungern eingegrenzt werden, und es ist keine Situation, in der zeitaufwändige Forschungsarbeiten durchgeführt werden können.
In diesem Fall sollten die Benutzerunternehmen selbst nachforschen. In diesem Sinne verlasse ich diesen Artikel mit der Absicht, meine eigenen Methoden zur Untersuchung und Analyse zusammenzufassen.
In diesem Artikel werde ich verschiedene Befehle verwenden und Nachforschungen anstellen, aber manchmal muss ich die PID von Tomcat im Voraus kennen. Es gibt verschiedene Möglichkeiten, die PID zu überprüfen, und Sie können sie mit dem folgenden Befehl überprüfen.
Wenn der einzige Prozess, der Java verwendet, Tomcat ist, können Sie dies mit dem Befehl pidof
überprüfen.
# pidof java
3344
Wenn Sie nicht sicher sind, ob es sich nur um Tomcat handelt, sollten Sie "jcmd" verwenden, um es aufzulisten und die Tomcat-PID zu bestimmen.
# jcmd -l
3344 org.apache.catalina.startup.Bootstrap-Start ← Dies ist die PID von Tomcat
4894 jdk.jcmd/sun.tools.jcmd.JCmd -l
Geben Sie die PID von Tomcat an und überprüfen Sie den Nutzungsstatus, z. B. den Speicher, mit dem Befehl top.
# top -p 3344
top - 11:22:30 up 23 min, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3939.0 total, 3295.9 free, 273.2 used, 369.9 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 3445.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3344 root 20 0 4204172 190864 28536 S 0.0 4.7 0:03.04 java
In den Tomcat-Startoptionen (JVM-Startoptionen) können Sie "-Xms", "-Xmx" usw. angeben und die von Tomcat verwendete Speichergröße festlegen.
Als Einstellmethode
--Stellen Sie das ~ / bash_profile
des Tomcat-Benutzers ein, um die Umgebungsvariable CATALINA_OPTS
zu exportieren
{tomcat-root} / bin / setenv.sh
angebenWenn es keine Tomcat-Umgebungskonstruktionsprozedur und -materialien, mit Ansible erstellte Skripte usw. gibt, Manchmal ist es schwierig zu überprüfen, was gestartet werden soll. (Besonders wenn Sie die Entwicklungsfirma bitten, die Umgebung zu erstellen, zu entwickeln und freizugeben und den Server als Benutzerfirma zu pflegen, ist dies besonders problematisch.)
In einem solchen Fall können Sie mit jcmd überprüfen, welche Art von JVM-Option der derzeit ausgeführte Tomcat derzeit ausführt.
Sie benötigen Ihre Tomcat-PID im Voraus, um dies zu überprüfen.
# jcmd -l
899 org.apache.catalina.startup.Bootstrap start
4894 jdk.jcmd/sun.tools.jcmd.JCmd -l
# jcmd 899 VM.flags
899:
-XX:CICompilerCount=2 -XX:InitialHeapSize=62914560 -XX:MaxHeapSize=991952896 -XX:MaxNewSize=330301440 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=20971520 -XX:OldSize=41943040 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Es ist möglich zu überprüfen, wie die Parametereinstellungen wie oben beschrieben sind, z. B. "-XX: MaxHeapSize", das "-Xmx" entspricht.
Ein Heap-Dump ist wie ein Snapshot-Protokoll der Java-Speichernutzung. Wenn Sie einen Heap-Dump abrufen und analysieren, können Sie irgendwie verstehen, wie Java Speicher verwendet. Hier wird mit jcmd ein Heap-Dump erfasst, der von Java 7 aus verwendet werden kann.
# jcmd -l
899 org.apache.catalina.startup.Bootstrap start
4894 jdk.jcmd/sun.tools.jcmd.JCmd -l
# jcmd 899 GC.heap_dump /var/log/heapdump/heapdmp.hprof
899:
Heap dump file created
# ls
heapdmp.hprof
Überprüfen Sie den von jcmd erfassten Heap-Dump mit einem Tool namens Java Visual VM. Die Analyse erfolgt in der lokalen PC-Umgebung (Umgebung mit GUI), JRE muss jedoch im Voraus installiert werden.
In meiner Umgebung wurde Java 1.8 eingerichtet und der Pfad war vorhanden.
$ java -version
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Führen Sie in dieser Umgebung den folgenden Befehl aus, um das Java Visual VM-Tool zu starten.
$ jvisualvm
Geben Sie die von Open File erhaltene Heap-Dump-Datei an und öffnen Sie sie.
Es scheint, dass Sie überprüfen können, ob zusätzliche Objekte aus dem Heap-Dump erstellt werden. Meine Erwartung war jedoch, dass es schön wäre, den Status der Speichernutzung und die Freigabe des Speichers durch GC in der Grafik zu sehen. Daher kann der Speicherauslastungsstatus nur von diesem Heap-Dump erfasst werden, die Ursache kann identifiziert werden und er kann als Auslöser für eine permanente Reaktion verwendet werden. Ich dachte, es wäre schwierig.
Es scheint möglich zu sein, den Status der Speichernutzung usw. mit einem Tool namens JConsole grafisch zu analysieren. https://docs.oracle.com/javase/jp/8/docs/technotes/guides/management/jconsole.html
Hier wird die JVM von JConsole über den JMX-Agenten für Tomcat überwacht, der auf dem CentOS-Server vom lokalen PC aus erstellt wurde.
Ich denke, es gibt verschiedene Möglichkeiten, die JVM-Startoption von Tomcat anzugeben, aber hier fügen Sie die Einstellung mit der in setenv.sh angegebenen Methode hinzu.
{tomcat-root}/bin/setenv.sh
#!/bin/sh
JAVA_OPTS="-server -Xms512M -Xmx2G -Dspring.profiles.active=production -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.33.10"
Dcom.sun.management.jmxremote.port
gibt den vom JMX-Agenten verwendeten Port an.
Angenommen, Tomcat verwendet Port 8080, habe ich einen anderen Port angegeben.
Darüber hinaus wird der Parameter "Djava.rmi.server.hostname" angegeben, um vom lokalen PC aus remote auf den Tomcat-Server zuzugreifen und eine JVM-Überwachung durchzuführen. Wenn Sie diesen Parameter nicht angeben, wird beim Versuch, eine Verbindung zu "192.168.33.10: 8888" in JConsole herzustellen, die Meldung "Sichere Verbindung fehlgeschlagen. Möchten Sie es unsicher wiederholen?" Angezeigt. Ich habe es versucht, konnte aber keine Verbindung herstellen. Seien Sie also vorsichtig, wenn Sie Fernzugriff benötigen.
Überprüfen Sie nach den obigen Einstellungen und dem Neustart von Tomcat, ob der angegebene Port "8888" ordnungsgemäß abgehört wird.
# systemctl restart tomcat
# ss -antup | grep 8888
tcp LISTEN 0 50 *:8888 *:* users:(("java",pid=4211,fd=17))
# ps -ef | grep jmx
Starten Sie das jconsole-Tool mit dem folgenden Befehl und überprüfen Sie die Speichernutzung. Der folgende Befehl wird vom lokalen PC ausgeführt. Bitte beachten Sie, dass der Befehl jconsole nur ausgeführt werden kann, wenn die JRE vorinstalliert ist und der Pfad korrekt ist.
jconsole 192.168.33.10:8888
Die Registerkarte Übersicht bietet eine grafische Ansicht darüber, wie Speicher, Threads, Klassen, CPU-Auslastung usw. im Laufe der Zeit verwendet werden. Es scheint, dass die Informationen auf dieser Registerkarte "Übersicht" für die Analyse ausreichen. Überprüfen wir jedoch den Inhalt der anderen Registerkarten.
GCViewer https://github.com/chewiebug/GCViewer/wiki/Changelog
Die JConsole-Analyse konnte bestätigen, wie oft GC auftrat, wusste jedoch nicht, wann GC auftrat. Holen Sie sich also das GC-Protokoll und überprüfen Sie mit GCViewer die Häufigkeit des Auftretens von GC und die von GC freigegebene Speichermenge sowie den Status der Speichernutzung.
Um das GC-Protokoll abzurufen, legen Sie die JVM-Optionen von Tomcat wie folgt fest:
{tomcat-root}/bin/setenv.sh
JAVA_OPTS="-server -Xms512M -Xmx2G -Dspring.profiles.active=production -verbose:gc -Xlog:gc*=info:file=/var/log/gclog/gc.log:time,uptime,level,tags:filecount=1,filesize=10m"
Starten Sie nach Abschluss der obigen Einstellungen den Tomcat-Dienst neu und lassen Sie ihn eine Weile stehen. (Lassen Sie die Web-App auf Tomcat eine Weile funktionieren.)
Wenn ich das erfasste Protokoll mit gcviewer anzeige, sieht es folgendermaßen aus.
Es wird auf verschiedene Arten angezeigt und ich bin mir nicht sicher, welche Farbe welche Rolle spielt. Sie können in der Menüansicht anzeigen / ausblenden, wie jede Farbe aussieht.
Die Auswirkungen der einzelnen werden im Folgenden kurz erläutert.
-PrintGCDetails
angegeben ist. In Java 9 oder höher muss jedoch der Parameter -Xlog: gc *
angegeben werden.-PrintGCDetails
angegeben ist. In Java 9 oder höher muss jedoch der Parameter -Xlog: gc *
angegeben werden.Wenn Sie weiterhin die angegebene Größe von -Xmx erreichen, können Sie feststellen, dass Full GC häufig auftritt. Wenn die Größe des Heaps nach der vollständigen GC abnimmt, scheint die Häufigkeit der vollständigen GC tendenziell abzunehmen.
Es gab jedoch eine Zeit, in der eine vollständige GC nicht häufig auftrat und die obere Grenzgröße auch dann erhalten blieb, wenn die obere Grenzgröße feststeckte.
Anstelle von Total Heap werden der Young-Bereich (Young Generation: Orange) und der Old-Bereich (Tenured Generation: Pink) als Aufschlüsselung angezeigt, und der Speichernutzungsstatus wird in Kombination mit Full GC analysiert.
Als ich Google durchsuchte und die JVM-Option aktivierte, um das GC-Protokoll abzurufen, war dies die folgende Option, also habe ich es versucht.
{tomcat-root}/bin/setenv.sh
JAVA_OPTS="-server -Xms512M -Xmx2G -Dspring.profiles.active=production -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/var/log/gclog/gc.log"
Nach Abschluss der obigen Einstellungen funktionierte die mit Tomcat erstellte Webanwendung nicht mehr, als ich den Tomcat-Dienst neu startete. Als ich untersuchte, warum es nicht mehr funktionierte, fand ich den folgenden Fehler.
{tomcat-root}/logs/catalina.out
Unrecognized VM option 'PrintGCDateStamps'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAM
Anscheinend sind einige JVM-Parameter in Java 9 oder höher nicht mehr verfügbar (JVM kann bei Verwendung nicht gestartet werden). Daher müssen Sie den nicht verfügbaren Parameter durch einen anderen Parameter ersetzen.
https://docs.oracle.com/javase/9/tools/java.htm#JSWOR624
Informationen zu Ersatzparametern, die als Referenz verwendet werden können, finden Sie im Abschnitt "Konvertieren von GC-Protokollierungsflags in Xlog" auf dieser Site. Es werden jedoch nicht alle Parameter eins zu eins ersetzt, was etwas verwirrend ist.
In der folgenden Grafik ist die Speichernutzung seit einiger Zeit nicht mehr auf etwa 1,4 GB gesunken.
Wenn Sie sich den Thread-Status um 20:41 ansehen, als die Speichernutzung plötzlich zunahm, können Sie sehen, dass die Anzahl der Threads ungefähr zur gleichen Zeit ihren Höhepunkt erreichte. Da jedoch die Anzahl der Thread-Ausführungen innerhalb weniger Minuten die Untergrenze erreicht hat, wird spekuliert, dass ein vorübergehender gleichzeitiger häufiger Zugriff aufgetreten sein könnte.
Die Tatsache, dass sich die Heap-Speichernutzung auch nach dem Absinken der Anzahl der Threads überhaupt nicht verbessert hat, bedeutet, dass möglicherweise Objekte vorhanden sind, die auch bei einem GC nicht zerstört werden.
Wenn Sie den Nutzungsstatus wie den Serverspeicher zu diesem Zeitpunkt mit dem Befehl top
überprüfen, sieht dies folgendermaßen aus.
# top -p 923
top - 11:53:47 up 1:01, 1 user, load average: 0.00, 0.03, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
top - 11:54:02 up 1:01, 1 user, load average: 0.00, 0.03, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.3 hi, 0.3 si, 0.0 st
MiB Mem : 3939.0 total, 1342.6 free, 1657.3 used, 939.1 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 2060.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
923 root 20 0 4278196 1.5g 31744 S 0.0 39.7 1:09.33 java
--VIRT Virtual Image. Alle reservierten virtuellen Speicher. Beinhaltet die Nutzung des getauschten Speichers. (Einheit: kb) ―― Da es sich um ungefähr 4 GB handelt, können Sie sehen, dass die Verarbeitung, die den Speicher bis zu 4 GB verwenden musste, einschließlich der ausgetauschten Verarbeitung, für Tomcat erfolgte, das durch Angabe von 2 GB mit -Xmx ausgeführt wurde. --RES Die Größe des verwendeten physischen Speichers, nicht ausgetauscht.
Wenn es sich nur um einen temporären Fokus handelt, müssen Sie den Parameter -Xmx nicht überprüfen. Wenn dies jedoch häufig vorkommt, müssen Sie möglicherweise das maximale Speichervolumen erhöhen.
Hier ist ein Diagramm, in dem sich der Speicherauslastungsstatus sofort vor 21:00 Uhr verbessert hat.
Das Ergebnis des Befehls top in diesem Zustand
# top -p 923
top - 12:04:03 up 1:11, 1 user, load average: 0.09, 0.04, 0.01
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3939.0 total, 1340.3 free, 1659.6 used, 939.1 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 2058.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
923 root 20 0 4278196 1.5g 31744 S 0.3 39.8 1:12.06 java
Insbesondere haben sich die Werte von VIRT, RES, SHR usw. nicht geändert. Daraus können wir ersehen, dass der Befehl top nur den Maximalwert des Speichers sehen kann, der vorübergehend als Snapshot hochgesprungen ist.
Recommended Posts