Profilerstellung für Go-Code

Auf dieser Seite wird beschrieben, wie Sie Ihre Go-Anwendung so ändern, dass Datenprofile erstellt und an Ihr Google Cloud-Projekt gesendet werden. Allgemeine Informationen zur Profilerstellung finden Sie unter Konzepte der Profilerstellung.

Profiltypen für Go:

  • CPU-Zeit
  • Heap
  • Zugewiesener Heap
  • Konflikt (Go-Mutex)
  • Threads (Go-Goroutine)

Unterstützte Go-Sprachversionen:

Unterstützte Profiler-Agent-Versionen:

  • Der neueste Release des Agents wird unterstützt. Im Allgemeinen werden Releases, die älter als ein Jahr sind, nicht unterstützt. Wir empfehlen, die neueste veröffentlichte Version des Agents zu verwenden.

Unterstützte Betriebssysteme:

  • Linux: Die Profilerstellung für Go-Anwendungen wird für Linux-Kernel unterstützt, deren Standard-C-Bibliothek mit glibc oder mit musl implementiert wurde. Konfigurationsinformationen zu Linux Alpine-Kernels finden Sie unter Mit Linux Alpine ausführen.

Unterstützte Umgebungen:

Profiler API aktivieren

Sorgen Sie vor Verwendung des Profiler-Agents dafür, dass die zugrunde liegende Profiler API aktiviert ist. Sie können den Status der API prüfen und sie bei Bedarf über die Google Cloud-Befehlszeile oder die Google Cloud Console aktivieren:

gcloud-CLI

  1. Wenn Sie die Google Cloud-Befehlszeile noch nicht auf Ihrer Workstation installiert haben, lesen Sie die Dokumentation zur Google Cloud-Befehlszeile.

  2. Führen Sie dazu diesen Befehl aus:

    gcloud services enable cloudprofiler.googleapis.com
    

Weitere Informationen finden Sie unter gcloud services.

Google Cloud Console

  1. Enable the required API.

    Enable the API

  2. Wenn API aktiviert angezeigt wird, ist die API bereits aktiviert. Falls nicht, klicken Sie auf die Schaltfläche Aktivieren.

Dienstkonto eine IAM-Rolle zuweisen

Wenn Sie Ihre Anwendung auf Google Cloud-Ressourcen bereitstellen, das Standarddienstkonto verwenden und die Rollenzuweisungen für dieses Dienstkonto nicht geändert haben, können Sie diesen Abschnitt überspringen.

In folgenden Fällen müssen Sie dem Dienstkonto die IAM-Rolle Cloud Profiler-Agent (roles/cloudprofiler.agent) zuweisen:

  1. Sie verwenden das Standarddienstkonto, haben aber seine Rollenzuweisungen geändert.
  2. Sie verwenden ein vom Nutzer erstelltes Dienstkonto.
  3. Sie verwenden Workload Identity und gewähren dem Kubernetes-Dienstkonto die Rolle „Cloud Profiler-Agent“.

Sie können einem Dienstkonto eine IAM-Rolle mithilfe der Google Cloud Console oder der Google Cloud CLI zuweisen. Sie können beispielsweise den Befehl gcloud projects add-iam-policy-binding verwenden:

gcloud projects add-iam-policy-binding GCP_PROJECT_ID \
    --member serviceAccount:MY_SVC_ACCT_ID@GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/cloudprofiler.agent

Ersetzen Sie vor dem Ausführen des Befehls Folgendes:

  • GCP_PROJECT_ID: Ihre Projekt-ID.
  • MY_SVC_ACCT_ID: Name Ihres Dienstkontos.

Weitere Informationen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Cloud Profiler verwenden

Zur Verwendung von Profiler müssen Sie das Paket in Ihre Anwendung importieren und Profiler dann so früh wie möglich in der Anwendung initialisieren. Dies gilt für alle unterstützten Umgebungen.

Sie können die Erstellung von Mutex-Konfliktprofilen aktivieren (auf der Oberfläche "Konflikt" genannt). Legen Sie dafür die Konfigurationsoption MutexProfiling auf true fest.

Weitere Informationen zur Profiler API, einschließlich aller Konfigurationsoptionen, finden Sie in den öffentlichen API-Dokumenten.

Compute Engine

Legen Sie für Compute Engine in der Datei profiler.Config für Service einen Namen für den Dienst fest, für den ein Profil erstellt wird, und legen Sie optional für ServiceVersion die Dienstversion fest:


// snippets is an example of starting cloud.google.com/go/profiler.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	cfg := profiler.Config{
		Service:        "myservice",
		ServiceVersion: "1.0.0",
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",

		// For OpenCensus users:
		// To see Profiler agent spans in APM backend,
		// set EnableOCTelemetry to true
		// EnableOCTelemetry: true,
	}

	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(cfg); err != nil {
		// TODO: Handle error.
	}
}

Wenn Abhängigkeiten in Ihrem Quellcode manuell abgerufen werden, müssen Sie möglicherweise folgenden Parameter zu Ihrem Build-Skript oder Dockerfile hinzufügen:

go get cloud.google.com/go/profiler

GKE

Legen Sie für GKE in profiler.Config für Service einen Namen für den Dienst fest, für den ein Profil erstellt wird, und legen Sie optional für ServiceVersion die Dienstversion fest:


// snippets is an example of starting cloud.google.com/go/profiler.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	cfg := profiler.Config{
		Service:        "myservice",
		ServiceVersion: "1.0.0",
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",

		// For OpenCensus users:
		// To see Profiler agent spans in APM backend,
		// set EnableOCTelemetry to true
		// EnableOCTelemetry: true,
	}

	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(cfg); err != nil {
		// TODO: Handle error.
	}
}

Wenn Abhängigkeiten in Ihrem Quellcode manuell abgerufen werden, müssen Sie möglicherweise folgenden Parameter zu Ihrem Build-Skript oder Dockerfile hinzufügen:

go get cloud.google.com/go/profiler

App Engine

Für die flexible App Engine-Umgebung und die App Engine-Standardumgebung sind die Codeergänzungen mit denen für Compute Engine und GKE nahezu identisch. Es gibt jedoch eine Ausnahme. In beiden App Engine-Umgebungen werden die Parameter Service und ServiceVersion aus der Umgebung abgeleitet, sodass Sie diese nicht angeben müssen.


// appengine is an example of starting cloud.google.com/go/profiler on
// App Engine.
package main

import (
	"cloud.google.com/go/profiler"
)

func main() {
	// Profiler initialization, best done as early as possible.
	if err := profiler.Start(profiler.Config{
		// Service and ServiceVersion can be automatically inferred when running
		// on App Engine.
		// ProjectID must be set if not running on GCP.
		// ProjectID: "my-project",
	}); err != nil {
		// TODO: Handle error.
	}
}

Wenn Sie die Anwendung lokal ausführen, müssen Sie die ProjectID (die ID Ihres Google Cloud-Projekts) und den Parameter Service in profiler.Config festlegen, da sie nicht aus einer lokalen Umgebung abgeleitet werden können. Sie müssen ServiceVersion nicht festlegen.

Wenn Sie die App Engine-Standardumgebung verwenden, finden Sie unter Anwendungen zu Go 1.11 migrieren ausführliche Informationen zu den Änderungen, die Sie möglicherweise an Ihrer Anwendung vornehmen müssen. Außerdem müssen Sie mindestens Version 226.0.0 der Google Cloud CLI verwenden. Führen Sie folgenden Befehl aus, um Google Cloud CLI zu aktualisieren:

gcloud components update

So führen Sie Ihre Anwendung aus:

  1. Aktualisieren Sie die Abhängigkeiten:

    go get cloud.google.com/go/profiler
    
  2. Stellen Sie die Anwendung in Ihrer flexiblen App Engine-Umgebung oder Ihrer App Engine-Standardumgebung bereit:

    gcloud app deploy [DEPLOYMENT]
    

    Dabei ist DEPLOYMENT der Pfad zu Ihrer Konfigurationsdatei. DEPLOYMENT könnte beispielsweise main/app.yaml sein.

Daten analysieren

Nachdem Profiler Daten erfasst hat, können Sie diese mit der Profiler-Oberfläche ansehen und analysieren.

Rufen Sie in der Google Cloud Console die Seite Profiler auf:

Gehen Sie zum Profiler.

Sie können diese Seite auch über die Suchleiste finden.

Argumente für Dienstnamen und -versionen

Wenn Sie den Profiler-Agent laden, geben Sie zu dessen Konfiguration ein Argument für den Dienstnamen und ein optionales Argument für die Dienstversion an.

Profiler kann Daten für alle Replikate des unter Dienstname angegebenen Dienstes erfassen. Der Profiler-Dienst hat eine durchschnittliche Erfassungsrate von einem Profil pro Minute für jede Kombination aus Dienstversion und Zone jedes Dienstnamens.

Beispielsweise erstellt Profiler für einen Dienst mit zwei Versionen, dessen Replikate in drei Zonen ausgeführt werden, durchschnittlich sechs Profile pro Minute.

Wenn Sie für die Replikate unterschiedliche Dienstnamen verwenden, werden Dienstprofile häufiger als nötig mit einem entsprechend höheren Overhead erstellt.

Berücksichtigen Sie beim Auswählen eines Dienstnamens Folgendes:

  • Wählen Sie einen Namen aus, der den Dienst in Ihrer Anwendungsarchitektur klar darstellt. Wenn Sie nur einen einzigen Dienst oder eine einzige Anwendung ausführen, spielt der Dienstname eine untergeordnete Rolle. Er gewinnt aber an Bedeutung, wenn Ihre Anwendung beispielsweise in Form mehrerer Mikrodienste ausgeführt wird.

  • Achten Sie darauf, keine prozessspezifischen Werte wie eine Prozess-ID im String für den Dienstnamen zu verwenden.

  • Der String für den Dienstnamen muss diesem regulären Ausdruck entsprechen:

    ^[a-z0-9]([-a-z0-9_.]{0,253}[a-z0-9])?$

Es empfiehlt sich, einen statischen String wie imageproc-service als Dienstnamen zu verwenden.

Die Dienstversion ist optional. Wenn Sie die Dienstversion angeben, kann Profiler Profilinformationen aus mehreren Instanzen aggregieren und korrekt anzeigen. Sie können so verschiedene Versionen Ihrer Dienste kennzeichnen, wenn diese bereitgestellt werden. Die Profiler-Oberfläche ermöglicht Ihnen, die Daten nach Dienstversion zu filtern. So können Sie die Leistung von älteren und neueren Versionen des Codes vergleichen.

Obwohl der Wert des Dienstversionsarguments ein Freitextstring ist, sehen die Werte für dieses Argument meist wie Versionsnummern aus, zum Beispiel 1.0.0 oder 2.1.2.

Agent-Logging

Der Profiler-Agent kann Fehlerbehebungsinformationen in seine Logs schreiben. Agent-Logging ist standardmäßig deaktiviert.

Zum Aktivieren von Agent-Logging legen Sie beim Starten des Agents die Option DebugLogging auf true fest:

profiler.Start(profiler.Config{..., DebugLogging: true});

Fehlerbehebung

In diesem Abschnitt werden Probleme aufgeführt, die speziell bei der Profilerstellung für Go-Anwendungen auftreten. Informationen zu häufig auftretenden Problemen finden Sie unter Fehlerbehebung.

Verhalten Ursache Lösung
Es werden keine CPU-Zeitprofile für Anwendungen erfasst, die mit -buildmode=c-archive erstellt wurden. Heap-, Konflikt- und Thread-Profile werden aber erfasst. GitHub-Problem Standardmäßig ist die CPU-Profilerstellung für Go-Anwendungen nicht aktiviert, wenn das Flag -buildmode den Wert c-archive oder c-shared hat. Fügen Sie
signal.Notify(make(
chan os.Signal), syscall.SIGPROF)
einen Aufruf vor dem Aufrufen von profiler.Start hinzu.
Antwort auf GitHub-Problem.

Mit Linux Alpine ausführen

Der Go-Profiler-Agent für Linux Alpine wird nur für Google Kubernetes Engine-Konfigurationen unterstützt.

Authentifizierungsfehler

Wenn Sie Docker-Images wie golang:alpine oder nur alpine verwenden, die mit Linux Alpine ausgeführt werden, wird möglicherweise der folgende Authentifizierungsfehler angezeigt:

connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"

Der Fehler ist nur sichtbar, wenn Agent-Logging aktiviert ist. Standardmäßig gibt der Agent für Go keine Lognachrichten aus.

Der Fehler zeigt an, dass die Root-SSL-Zertifikate für die Docker-Images mit Linux Alpine nicht standardmäßig installiert sind. Diese Zertifikate sind erforderlich, damit der Profiler-Agent mit der Profiler API kommunizieren kann. Fügen Sie Ihrem Dockerfile den folgenden apk-Befehl hinzu, um diesen Fehler zu beheben:

FROM alpine
...
RUN apk add --no-cache ca-certificates

Sie müssen dann Ihre Anwendung neu erstellen und noch einmal bereitstellen.

Nächste Schritte