Untersuchungsmethode, wenn die CPU des Servers, auf dem Java ausgeführt wird, schwer ist

Was ist passiert: point_up:

Als ich mir Cloudwatch ansah, war die CPU-Auslastung beim Start der Instanz hoch, daher wurde ich gebeten, dies zu überprüfen.

Wenn Sie es nachschlagen, können Sie herausfinden, wie es geht, aber für Ihr eigenes Memorandum.

Umgebung

Red Hat Enterprise Linux Server release 7.5 (Auf AWS EC2)

Ist die CPU wirklich schwer: Denken:

Ist die CPU wirklich überlastet? Ist es nicht ein CloudWatch-Fehler? Überprüfen Sie dies mit dem Befehl sar. Wenn die Umgebung den Befehl sar nicht enthält, installieren Sie ihn.

$ sudo yum install sysstat

Dieses Mal trat es übrigens in der Produktionsumgebung auf, aber in der Produktionsumgebung ist es selten, dass Sie sich direkt anmelden können, sodass Sie auch das Produktionsprotokoll abrufen und die sa-Datei anzeigen können.

$sar -f <Dateipfad>
09:10:02 CPU%user     %nice   %system   %iowait    %steal     %idle
09:20:01 alle 3.97      0.00      0.35      0.00      0.01     95.67
09:30:01 alle 4.01      0.00      0.36      0.00      0.01     95.62
09:40:02 alle 3.87      0.00      0.42      0.00      0.01     95.69
09:50:01 alle 4.05      0.00      0.35      0.00      0.01     95.59
10:00:01 alle 4.04      0.00      0.37      0.00      0.01     95.58
10:10:01 alle 3.95      0.00      0.35      0.00      0.01     95.69
10:20:02 alle 3.98      0.00      0.36      0.00      0.01     95.65
10:30:01 alle 4.04      0.00      0.36      0.00      0.01     95.59
10:40:01 alle 3.81      0.00      0.41      0.00      0.01     95.76
10:50:02 alle 3.96      0.00      0.36      0.00      0.01     95.67
11:00:01 alle 4.14      0.00      0.35      0.00      0.01     95.49
11:10:01 alle 3.94      0.00      0.35      0.00      0.01     95.71

Sie können das Ergebnis so sehen. Wenn ich es mir ansehe, kann ich nicht sehen, dass die Last besonders hoch ist.

Wenn Sie sich die Cloudwatch ansehen, können Sie dasselbe Phänomen in der Staging-Umgebung beobachten. Reproduzieren Sie es also in der Staging-Umgebung. Außerdem sind 10 Minuten zu breit, also versuchen wir es mit 1 Minute.

$ vi /etc/cron.d/sysstat 

Ändern Sie die folgenden \ * / 10 in \ * / 1

# Run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
# 0 * * * * root /usr/lib64/sa/sa1 600 6 &
# Generate a daily summary of process accounting at 23:53
53 23 * * * root /usr/lib64/sa/sa2 -A

Starten Sie das Betriebssystem neu und überprüfen Sie

19:53:01 CPU%user     %nice   %system   %iowait    %steal     %idle
19:54:01 alle 68.91      0.00      3.04      0.05      0.01     28.00
19:55:01 alle 2.93      0.01      0.41      0.01      0.02     96.63
19:56:01 alle 8.20      0.00      0.86      0.02      0.01     90.91
19:57:01 alle 4.65      0.00      0.34      0.01      0.01     94.99
19:58:01 alle 0.26      0.00      0.07      0.00      0.01     99.67
19:59:01 alle 4.97      0.01      0.36      0.00      0.02     94.65
20:00:01 alle 4.93      0.00      0.39      0.00      0.01     94.67
20:01:01 alle 3.11      0.00      0.54      0.00      0.01     96.34
20:02:01 alle 4.97      0.00      0.38      0.00      0.01     94.64
20:03:01 alle 4.87      0.00      0.34      0.00      0.01     94.78

Ja. Die CPU ist stark ausgelastet.

Identifizieren von Threads, die unter starker Last stehen

Identifizieren Sie zunächst Prozesse mit hoher CPU-Auslastung

$ ps -aux

Sie können die CPU-Verbrauchsrate in der Spalte% CPU anzeigen. Diesmal war Tomcat 140 oder so. (Es gibt auch eine Möglichkeit, dies mit dem Befehl top zu überprüfen, aber ich habe den Befehl ps verwendet, da es diesmal schwer zu erkennen war.)

Überprüfen Sie dann, welcher Thread unter Last steht.

$ ps -L aux

Wenn dieser Befehl eingegeben wird, wird die folgende Ausgabe ausgegeben (erfolgt, wenn sich die CPU-Last beruhigt hat).

USER       PID   LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
test       1007  1016  0.4   56 16.8 6749028 1299196 ?     Sl   16:52   0:01 /usr/bin/java -Djava.util.logging.config.file=/opt/test/tomcat/conf/logging.properties -Djava
test       1007  1029  2.2   56 16.8 6749028 1299196 ?     Sl   16:52   0:05 /usr/bin/java -Djava.util.logging.config.file=/opt/test/tomcat/conf/logging.properties -Djava
test       1007  1032  1.6   56 16.8 6749028 1299196 ?     Sl   16:52   0:04 /usr/bin/java -Djava.util.logging.config.file=/opt/test/tomcat/conf/logging.properties -Djava
test       1007  1053  1.9   56 16.8 6749028 1299196 ?     Sl   16:52   0:04 /usr/bin/java -Djava.util.logging.config.file=/opt/test/tomcat/conf/logging.properties -Djava
test       1007  1057  0.0   56 16.8 6749028 1299196 ?     Sl   16:52   0:00 /usr/bin/java -Djava.util.logging.config.file=/opt/test/tomcat/conf/logging.properties -Djava

Notieren Sie sich hier die stark belastete PID und LWP.

Überprüfen Sie den Thread-Dump

Ich wusste es, aber der Hochlastprozess ist Jaba! ist. Überprüfen wir also den Thread-Dump: Flugzeug:

sudo -u test jstack -l <Hochlast-PID> > /tmp/jstack

So erhalten Sie den Thread-Dump. Wenn Sie es alle paar Minuten einnehmen, können Sie die Änderung sehen.

In / tmp / jstack sieht die Ausgabe wie folgt aus

"localhost-startStop-1" #17 daemon prio=5 os_prio=0 tid=0x00007f6fe0001db0 nid=0x5ee runnable [0x00007f700c062000]
   java.lang.Thread.State: RUNNABLE
        at org.springframework.asm.Type.getReturnType(Type.java:386)
        at org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor.visitMethod(AnnotationMetadataReadingVisitor.java:81)
        at org.springframework.asm.ClassReader.readMethod(ClassReader.java:1061)
        at org.springframework.asm.ClassReader.accept(ClassReader.java:729)
        at org.springframework.asm.ClassReader.accept(ClassReader.java:527)
        at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:64)
        at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:102)
        at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:102)
        - locked <0x00000006f3a459d8> (a org.springframework.core.type.classreading.CachingMetadataReaderFactory$1)
        at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:287)
        at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:272)
        at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:135)
        at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:289)
        at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:247)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:200)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:169)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:272)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525)
        - locked <0x0000000708be6ac8> (a java.lang.Object)

(Unten weggelassen)

Die Zahl nach 0x, in die dieses nid = 0x5ee geschrieben ist, ist der Wert, der durch Konvertieren des mit ps -L aux zuvor gesehenen LID in eine hexadezimale Zahl erhalten wird. Suchen Sie aus den vielen geschriebenen Thread-Dumps nach der LID, die mit der LID übereinstimmt.

Informationen zum Lesen des Thread-Dumps finden Sie auf der folgenden Website https://yohei-a.hatenablog.jp/entry/20150101/1420112104

Fazit

Als ich in den Thread-Dump schaute, konnte ich keine seltsamen Threads finden. Erstens verbraucht es beim Starten von Tomcat eine bestimmte Menge an CPU, und da in dieser Umgebung zwei Tomcats gestartet werden, dauert es einige Zeit, bis sich die CPU-Last beruhigt hat. Ich bin froh, dass es nicht ungewöhnlich war, aber ich habe viel über das Lesen des Thread-Dumps gelernt, also habe ich viel gelernt: entspannt:

Recommended Posts

Untersuchungsmethode, wenn die CPU des Servers, auf dem Java ausgeführt wird, schwer ist
Die Reihenfolge der Java-Methodenmodifikatoren ist festgelegt
Was ist die Hauptmethode in Java?
[Java] Behandlung von Java Beans in der Methodenkette
[Java] Ist es nicht erforderlich, "Identität" bei der Implementierung der equals () -Methode zu überprüfen?
Ursache ist nicht sichtbar, wenn Methoden anderer Klassen in Java aufgerufen werden
Wenn der Schwebeflug von Eclipse schwer zu sehen ist
Der Vergleich von enum ist == und gleich ist gut [Java]
[Java] Beim Schreiben der Quelle ... Memorandum ①
[Ruby] Denken, wenn sich vor der Methode kein Empfänger befindet (wie es aussieht)
So erhalten Sie den Namen einer Klasse / Methode, die in Java ausgeführt wird
Die Berechtigungsspezifikation der FileUtils-Methode ist eine Oktalzahl.
Gilt die Methode der primitiven spezialisierten IntFunction oder applyAsInt?
Die Idee, abzuschalten, wenn der Fehler nicht behoben ist
[Schienen] Wenn die Layoutänderung des Geräts nicht berücksichtigt wird
Java: Das Problem ist schneller, Stream oder Loop
Zeigt einen detaillierten Fehler in Logger an, wenn Java auf dem Server ausgeführt wird
Zusammenfassung der von der Spliterator-Merkmalsmethode #java zurückgegebenen Werte
[Swift] Ermittelt das Timing, wenn der Wert von textField geändert wird
Logback-Protokoll wird nicht ausgegeben, wenn die Serveranwendung geschlossen wird
Was ist die Zupfmethode?
Vorteile der statischen Java-Methode
5. Tag von Java
Was ist die Initialisierungsmethode?
[Java-Anfänger] Konvertierung von Zeichenfolge in numerischen Wert - Was ist die parseInt-Methode der Integer-Klasse? ~
Wechseln Sie die von SDKMAN installierte Java-Version, wenn Sie Verzeichnisse verschieben
Abhilfe für "Ein Server läuft bereits." Fehler beim Ausführen von Rails s
Die in /lib/calendars.properties von Java jre festgelegte Millisekunde ist UTC
Das Verhalten von JS auf Java SE 8 Nashorn änderte sich plötzlich
Ist die von Ihnen verwendete Version von Elasticsearch mit Java 11 kompatibel?
[Java] Löschen Sie die Elemente von List
'% 02d' Was ist der% von% 2?
[Java Edition] Geschichte der Serialisierung
Wo ist die Zeitzone von Javas LocalDateTime.now ()?
Java-Vergleich mit der compareTo () -Methode
Informationen zur Rolle der Initialisierungsmethode
[Java] So legen Sie den Proxy beim Starten von Java fest
Was für eine Methode ist define_method?
Der Ursprung von Java-Lambda-Ausdrücken
Rufen Sie die Super-Methode in Java auf
Fälle, in denen Benutzer beim Bearbeiten einer App abgemeldet sind (Rails)
[Java Servlet] Die Straße von Senri ist auch der fünfte Schritt von einem Schritt
[Java Servlet] Die Straße von Senri ist auch ein Schritt zum ersten
[Java Servlet] Die Straße von Senri ist auch der dritte Schritt vom ersten Schritt
Fehler, wenn das in SpringWebFlux verwendete Mitglied der Entity-Klasse endgültig ist
[Java small story] Überwachen Sie, wann der Liste ein Wert hinzugefügt wird
So ermitteln Sie die Gesamtzahl der Seiten beim Paging in Java
So ermitteln Sie den absoluten Pfad eines in Java ausgeführten Verzeichnisses
Ab Java9 werden Klassenkonstruktoren, die primitiven Typen entsprechen, als veraltet markiert.
[Java Servlet] Die Straße von Senri ist auch der vierte Schritt vom ersten Schritt
Was tun, wenn die Meldung "Ein Server läuft bereits" angezeigt wird. Fehler beim Versuch, den Rails-Server zu starten
Java / Kotlin: Berechnen Sie den Quotienten, indem Sie die Anzahl der gültigen Zahlen angeben, wenn er nicht durch die Division (Division) von BigDecimal teilbar ist.
[Java] [Microsoft] Beachten Sie Folgendes, wenn Sie den SQL Server-JDBC-Treiber in eine JAR-Datei aufnehmen