Profilierung von Go-Code: Engpässe mit pprof und trace finden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

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=30


Nach Abschluss der Erfassung öffnet sich die interaktive pprof-Konsole. Die nützlichsten Befehle sind:



  • top — Zeigt die Funktionen an, die die meiste CPU-Zeit verbrauchen
  • list <Funktion> — Zeigt die zeilenweise Aufschlüsselung der Zeit
  • web — Ö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.ToLower


Erfassung eines Speicherprofils



Zur Analyse der Speichernutzung:



go tool pprof http://localhost:8080/debug/pprof/heap


Wichtige Befehle in pprof für den Speicher:



  • top — Funktionen, die den meisten Speicher zuweisen
  • sample_index=alloc_space — Umschalten auf die insgesamt zugewiesene Speichermenge
  • sample_index=inuse_space — Umschalten auf den aktuell genutzten Speicher
  • tr

Blogs

Buchempfehlungen