Profilierung von Go-Code: Engpässe finden
Die Optimierung der Leistung ist eine der Hauptaufgaben eines Entwicklers, insbesondere bei hochbelasteten Systemen in Go. Bevor man jedoch etwas optimiert, muss man genau wissen, welche Codeabschnitte die Engpässe sind. Dafür gibt es das Profiling – die Erfassung und Analyse von Metriken der Programmausführung.
In diesem Artikel werden wir uns ansehen, wie man Go-Anwendungen mit den integrierten Tools pprof und trace profiliert. Sie erfahren, wie Sie Problemstellen in Bezug auf CPU, Speicher, Blockaden und Goroutinen finden und wie Sie die gewonnenen Daten interpretieren.
Was ist Profiling und warum wird es benötigt?
Profiling ist der Prozess der Datenerfassung über die Arbeitsweise eines Programms während seiner Ausführung. Diese Daten helfen, Fragen zu beantworten:
- Welche Funktionen verbrauchen die meiste Prozessorzeit?
- Wo findet die Zuweisung großer Speichermengen statt?
- Welche Goroutinen werden blockiert und woran?
- Wie viel Zeit nimmt ein Systemaufruf oder eine Ein-/Ausgabeoperation in Anspruch?
Go bietet leistungsstarke Tools für das Profiling direkt aus dem Kasten. Die wichtigsten sind net/http/pprof für Webanwendungen und runtime/pprof für CLI-Dienstprogramme.
Das Tool pprof: CPU- und Memory-Profile
pprof ist das Hauptwerkzeug für das Profiling von Go. Es kann CPU-, Speicher-, Blockierungs-, Goroutinen- und Mutex-Konkurrenzprofile erstellen.
Hinzufügen von pprof zu einer Webanwendung
Der einfachste Weg, Profiling zu integrieren, ist das Importieren des Pakets net/http/pprof:
package main
import ( "net/http" _ "net/http/pprof" // registriert die pprof-Handler)
func main() { // Ihre Anwendung http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}Danach sind unter der Adresse /debug/pprof/ verschiedene Profile verfügbar. Zum Beispiel:
/debug/pprof/profile— CPU-Profil (standardmäßig 30 Sekunden)/debug/pprof/heap— Speicherprofil (heap)/debug/pprof/goroutine— Dump aller Goroutinen/debug/pprof/block— Blockierungsprofil
Erfassung eines CPU-Profils
Verwenden Sie den folgenden Befehl, um ein CPU-Profil zu erfassen:
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30Nach Abschluss der Erfassung öffnet sich die interaktive pprof-Konsole. Die nützlichsten Befehle sind:
top— Zeigt die Funktionen an, die die meiste CPU-Zeit verbrauchenlist <Funktion>— Zeigt die zeilenweise Aufschlüsselung der Zeitweb— Öffnet den Aufrufgraphen im Browser (erfordert Graphviz)peek <Funktion>— Zeigt aufrufende und aufgerufene Funktionen
Beispiel einer top-Ausgabe:
Showing nodes accounting for 3.50s, 70% of 5.00s total flat flat% sum% cum cum% 1.20s 24.00% 24.00% 1.20s 24.00% encoding/json.(*Decoder).Decode 0.80s 16.00% 40.00% 0.80s 16.00% runtime.mallocgc 0.60s 12.00% 52.00% 1.80s 36.00% main.processData 0.50s 10.00% 62.00% 0.50s 10.00% runtime.memmove 0.40s 8.00% 70.00% 0.40s 8.00% strings.ToLowerErfassung eines Speicherprofils
Zur Analyse der Speichernutzung:
go tool pprof http://localhost:8080/debug/pprof/heapWichtige Befehle in pprof für den Speicher:
top— Funktionen, die den meisten Speicher zuweisensample_index=alloc_space— Umschalten auf die insgesamt zugewiesene Speichermengesample_index=inuse_space— Umschalten auf den aktuell genutzten Speichertr