Node bereichert als Laufzeitumgebung für Javascript auf der Serverseite die Anwendungsszenarien von Javascript erheblich.
Allerdings ist die Node.js-Laufzeit selbst eine Blackbox. Wir können den Laufzeitstatus nicht erkennen und es ist schwierig, Online-Probleme zu reproduzieren .
Daher ist die Leistungsüberwachung der Grundstein für den „normalen Betrieb“ von Node.js-Anwendungen. Es können nicht nur jederzeit verschiedene Laufzeitindikatoren überwacht werden, sondern es kann auch bei der Behebung ungewöhnlicher Szenarioprobleme hilfreich sein.
Die Überwachung derkann in zwei Teile unterteilt werden:
Erfassung und Anzeige von Leistungsindikatoren
Erfassung und Analyse von Leistungsdaten
wie QPS, langsames HTTP, Verbindungsprotokolle zur Geschäftsverarbeitung usw.Aus dem Bild oben können Sie die Vor- und Nachteile der drei aktuellen Mainstream-Leistungsüberwachungslösungen von Node.js ersehen. Im Folgenden finden Sie eine kurze Einführung in die Zusammensetzung dieser drei Lösungen:
Prometheus
AliNode zu bilden.
Alinode ist eine erweiterte Laufzeit, die mit offiziellen Nodejs kompatibel ist und einige zusätzliche Funktionen bietet:
Agenthub ist ein residenter Prozess, der zum Sammeln von Leistungsindikatoren verwendet wird und melden Sie sie.
bilden einen geschlossenen Kreislauf aus Überwachung, Anzeige, Snapshot und Analyse, aber es gibt immer noch Risiken, wenn die Laufzeit
wird
Node.js Addon
zur Implementierung der Sampler-Die CPU-Zeitverbrauchsdaten des aktuellen Prozesses können über process.cpuUsage()
Die Einheit des Rückgabewerts ist Mikrosekunden.
Die Speicherzuordnungsdaten des aktuellen Prozesses können über process.memoryUsage()
abgerufen werden. Die Einheit des Rückgabewerts ist Bytes.
Wie aus der obigen Abbildung ersichtlich ist, enthält rss
Codesegmente ( Code Segment
), Stapelspeicher ( Stack
) und Heapspeicher ( Heap
):
können über v8.getHeapStatistics()
und v8.getHeapSpaceStatistics()
Die folgende Abbildung zeigt die Verteilung der Heapspeicherzusammensetzung von v8:
Der Heap-Speicherplatz wird zunächst in Leerzeichen und dann in Seiten unterteilt. Der Speicher wird entsprechend der 1-MB-Ausrichtung ausgelagert.
Neuer Raum: Raum der neuen Generation, der zum Speichern einiger Objektdaten mit einem relativ kurzen Lebenszyklus verwendet wird und in zwei Räume unterteilt ist (Raumtyp ist semi space
): from space
to space
Alter Raum : Der alte Generationsraum, der zum Speichern von Objekten verwendet wird, die von New Space
gefördert werden
: Speichert den von v8 kompilierten ausführbaren Code. Kartenraum
: Speichert das Zeigerobjekt der versteckten Klasse, auf die von Object verwiesen wird Gemäß der Laufzeit wird die Objektlayoutstruktur für den schnellen Zugriff auf Objektmitglieder verwendet,
die größer als 1 MB sind und nicht den Seiten zugeordnet werden
können
Mark-Sweep-Compact
-Algorithmus für das Objektrecycling in der alten GenerationScavenge
Algorithmus wird zum Recycling von Objekten in der neuen GenerationPrämisse: New space
ist in zwei Objekträume unterteilt: from
und to
Schritte:
Wenn der New space
voll ist
from space
führen Sie eine Breitendurchquerung durch
und stellen Sie fest, dass das überlebende (erreichbare) Objekt
Wenn das Kopieren endet, werden nur noch verbliebene Objekte in to space
verschoben, from space
Raum wird geleert
Old space
to space
to space
from space
Scavenge
beginnt
eignet sich für häufiges Recycling und unzureichenden Speicher. Bei großen Objekten hat die typische Raum-für-Zeit-Strategie den Nachteil, dass doppelt so viel Platz verschwendet wird wie bei
Drei Schritte: Markieren, Löschen und Organisieren
Old space
Schritte:
Markieren (dreifarbige Markierungsmethode).
marking queue
(expliziten Stapel) und markieren Sie diese Objekte als grau.pop
das Objekt jedes Mal aus marking queue
, markieren Sie espush
in marking queue
Sweep
.
Old space
, sodass der freigegebene Speicherplatz kontinuierlich und vollständig ist.durchführt, muss es das Programm stoppen, den gesamten Heap scannen und den Speicher zurückgewinnen, bevor das Programm erneut ausgeführt wird. Dieses Verhalten wird als vollständige Pause ( Stop-The-World
) bezeichnet.
Obwohl die aktiven Objekte in der neuen Generation klein sind und häufig recycelt werden, hat ein vollständiger Stopp nur geringe Auswirkungen. Die überlebenden Objekte in der alten Generation sind jedoch zahlreich und groß. und Pausen, die durch Markieren, Reinigen und Sortieren usw. verursacht werden. Es wird schwerwiegender sein.
Inkrementelles RecyclingDieses Konzept ähnelt tatsächlich ein wenig der Fiber-Architektur im React-Framework. Nur während der freien Zeit des Browsers wird der Fiber-Baum durchlaufen, um die entsprechenden Aufgaben auszuführen , Vermeidung von Anwendungsverzögerungen und Verbesserung der Anwendungsleistung.
Da v8 eine Standardspeicherbeschränkung für die neue und alte Generation hat
New space
32 MB für 64-Bit-Systeme und 16 MB für 32-Bit-Old space
700 MB für 32-Bit-Systeme.node
werden zwei Parameter zum Anpassen der oberen Speicherplatzgrenze der neuen und alten Generation bereitgestellt:
--max-semi-space-size
: Legen Sie den Maximalwert des New Space
fest--max-old-space-size
: Legen Sie den Maximalwert von Old Space
fest. spacenode
außerdem drei Möglichkeiten zum Anzeigen von GC-Protokollen:
--trace_gc
: Eine Protokollzeile beschreibt kurz die Zeit, den Typ, die Heap-Größenänderungen und die Ursachen jedes GC--trace_gc_verbose
: Zeigt jeden V8-Heap nach jedem GC an. Detaillierter Status des Speicherplatzes--trace_gc_nvp
: Detaillierte Schlüssel-Wert-Paarinformationen jedes GC, einschließlich GC-Typ, Pausenzeit, Speicheränderungen usw.Da das GC-Protokoll relativ primitiv ist und erfordert Für die sekundäre Verarbeitung können Sie v8-gc verwenden, das vom AliNode-Team entwickelt wurde. Das Log-Parser
-erstellt einen Snapshot des Heap-Speichers eines laufenden Programms und kann zur Analyse des Speicherverbrauchs und zur Änderung von
.heapsnapshot
Dateien
kann auf folgende Weise generiert werden:
mit Heapdump
Verwendung des Heap-Profils von v8
v8.getHeapSnapshot()
die vom integrierten v8-Modul von nodejs bereitgestellt wird
v8.writeHeapSnapshot(fileName)
Verwendung von v8-profiler-next
.heapsnapshot
in den Speicher der Chrome-Devtools-Symbolleiste hochgeladen werden. Die Ergebnisse werden wie folgt angezeigt:
Die Standardansicht ist Summary
. Hier müssen wir auf die beiden Spalten ganz rechts achten: Shallow Size
und Retained Size
Size
Retained Size
Shallow Size
die Größe des im v8-Heap-Speicher zugewiesenen Objekts anShallow Size
aller referenzierten Objekte des Objekts.Wenn festgestellt wird, dass Retained Size
im Objekt besonders groß ist, können Sie
die Comparison
weiter erweitern, um sie zu vergleichen Analysieren Sie die Heap-Snapshots von zwei verschiedenen Zeiträumen. Mit der Delta
Spalte können Sie die Objekte mit den größten Speicheränderungen herausfiltern.
führt ein Snapshot-Sampling der CPU durch, auf der das Programm ausgeführt wird, was zur Analyse der CPU-Zeit und des CPU-Anteils verwendet werden kann.
Es gibt mehrere Möglichkeiten, eine .cpuprofile
Datei zu generieren:
Dies ist eine 5-minütige CPU-Profil-Beispielsammlung
Die durchJavascript Profiler
.cpuprofile
Datei
Die Standardansicht ist die Heavy
-Ansicht. Hier sehen wir zwei Spalten: Self Time
und Total Time
Total Time
dieserSelf Time
selbst dar (ohne andere Aufrufe).Total Time
die Berechnung viel Zeit in Anspruch Self Time
. Sie können auch eine weitere Fehlerbehebung durchführen,
die Anwendung unerwartet abstürzt und beendet wird. Das System zeichnet in diesem Moment automatisch die Speicherzuordnungsinformationen, den Programmzähler und den Stapelzeiger sowie andere Schlüsselinformationen auf
. Drei Methoden zum Generieren von .core
Dateien:
ulimit -c unlimited
öffnet das Kernel-Limitnode --abort-on-uncaught-exception
Durch Hinzufügen dieses Parameters beim Starten des Knotens kann eine Kerndatei generiert werden, wenn in der Anwendung eine nicht erfasste Ausnahme auftritt.gcore <pid>
Nach Erhalt der .core
Datei Analyse
Die Diagnose kann über Tools wie mdb, gdb, lldb usw. erfolgen. Die eigentliche Ursache des Prozessabsturzes ist
llnode `which node` -c /path/to/core/dump
Durch die Überwachung kann beobachtet werden, dass der Heap-Speicher immer weiter zunimmt, sodass zur Fehlerbehebung
Anhand heapsnapshot
können wir analysieren und herausfinden, dass es ein newThing
Objekt gibt, das immer einen relativ großen Speicher verwaltet hat
unused
newThing
theThing
replaceThing
, die durch Abschlüsse verursacht werden,
gehören:
Daher müssen Sie sorgfältig abwägen, ob das Objekt im Speicher automatisch recycelt wird nicht automatisch recycelt werden, müssen Sie ein manuelles Recycling durchführen, z. B. das manuelle Setzen von Objekten auf null
, das Entfernen von Timern, das Aufheben der Bindung von Ereignis-Listenern usw.
. Dieser Artikel enthält eine detaillierte Einführung in das gesamte Leistungsüberwachungssystem von Node.js.
Zunächst werden die durch Leistungsüberwachung gelösten Probleme, ihre Komponenten und ein Vergleich der Vor- und Nachteile gängiger Lösungen vorgestellt.
Anschließend werden die beiden Hauptteile der Leistungsindikatoren und Snapshot-Tools ausführlich vorgestellt.
Abschließend wird ein einfacher Speicherverlustfall aus Beobachtung, Analyse und Fehlerbehebung reproduziert und häufige Speicherverlustsituationen und -lösungen zusammengefasst.
Ich hoffe, dieser Artikel kann jedem helfen, das gesamte Leistungsüberwachungssystem von Node.js zu verstehen.