Profilazione delle applicazioni Go

Questa pagina descrive come modificare l'applicazione Go per acquisire i dati di profilazione e inviarli al tuo progetto Google Cloud. Per informazioni generali sulla profilazione, vedi Concetti di profilazione.

Tipi di profilo per Go:

  • Tempo CPU
  • Heap
  • Heap allocato
  • Contesa (mutex Go)
  • Thread (goroutine Go)

Versioni del linguaggio Go supportate:

Versioni dell'agente di profilazione supportate:

  • È supportata la versione più recente dell'agente. In generale, le release più vecchie di un anno non sono supportate. Ti consigliamo di utilizzare la versione dell'agente rilasciata più di recente.

Sistemi operativi supportati:

  • Linux. La profilazione delle applicazioni Go è supportata per i kernel Linux la cui libreria C standard è implementata con glibc o con musl. Per informazioni di configurazione specifiche per i kernel Linux Alpine, vedi Esecuzione su Linux Alpine.

Ambienti supportati:

Attivazione dell'API Profiler

Prima di utilizzare l'agente di profilazione, assicurati che l'API Profiler sottostante sia abilitata. Puoi controllare lo stato dell'API e abilitarla, se necessario, utilizzando Google Cloud CLI o la console Google Cloud :

Interfaccia a riga di comando gcloud

  1. Se non hai ancora installato Google Cloud CLI sulla tua workstation, consulta la documentazione di Google Cloud CLI.

  2. Esegui questo comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Per ulteriori informazioni, vedi gcloud services.

Console Google Cloud

  1. Enable the required API.

    Enable the API

  2. Se viene visualizzato il messaggio API abilitata, l'API è già abilitata. In caso contrario, fai clic sul pulsante Attiva.

Concedi ruolo IAM al account di servizio

Se stai eseguendo il deployment dell'applicazione sulle risorse Google Cloud e se utilizzi il account di servizio predefinito e non hai modificato le concessioni di ruolo a questo account di servizio, puoi saltare questa sezione.

Se esegui una delle seguenti operazioni, devi concedere all'account di servizio il ruolo IAM Agente Cloud Profiler (roles/cloudprofiler.agent):

  1. Stai utilizzando il account di servizio predefinito, ma hai modificato le concessioni di ruolo.
  2. Stai utilizzando un account di servizio creato dall'utente.
  3. Stai utilizzando Workload Identity, concedi il ruolo Agente Cloud Profiler al account di servizio Kubernetes.

Puoi concedere un ruolo IAM a un account di servizio utilizzando la consoleGoogle Cloud o Google Cloud CLI. Ad esempio, potresti utilizzare il comando gcloud projects add-iam-policy-binding:

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

Prima di utilizzare il comando precedente, sostituisci quanto segue:

  • GCP_PROJECT_ID: il tuo ID progetto.
  • MY_SVC_ACCT_ID: il nome del account di servizio.

Per informazioni dettagliate, vedi Gestire l'accesso a progetti, cartelle e organizzazioni.

Utilizzo di Cloud Profiler

In tutti gli ambienti supportati, utilizzi Profiler importando il pacchetto nell'applicazione e inizializzando Profiler il prima possibile nell'applicazione.

Puoi attivare la profilazione della contesa di mutex ("Contesa" nell'interfaccia) impostando l'opzione di configurazione MutexProfiling su true.

Per ulteriori informazioni sull'API Profiler, incluse tutte le opzioni di configurazione, consulta la documentazione dell'API pubblica.

Compute Engine

Per Compute Engine, in profiler.Config imposta Service con un nome per il servizio di cui viene eseguito il profiling e, facoltativamente, imposta ServiceVersion con la versione del servizio:


// 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.
	}
}

Se nel codice sorgente sono presenti dipendenze recuperate manualmente, potresti dover aggiungere quanto segue allo script di build o al Dockerfile:

go get cloud.google.com/go/profiler

GKE

Per GKE, in profiler.Config imposta Service con un nome per il servizio di cui viene eseguito il profiling e, facoltativamente, imposta ServiceVersion con la versione del servizio:


// 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.
	}
}

Se nel codice sorgente sono presenti dipendenze recuperate manualmente, potresti dover aggiungere quanto segue allo script di build o al Dockerfile:

go get cloud.google.com/go/profiler

App Engine

Per l'ambiente flessibile App Engine e l'ambiente standard App Engine, le aggiunte di codice sono quasi identiche a quelle per Compute Engine e GKE. Esiste un'eccezione. In entrambi gli ambienti App Engine, i parametri Service e ServiceVersion derivano dall'ambiente, quindi non devi specificarli.


// 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.
	}
}

Quando esegui l'applicazione in locale, imposta i parametri ProjectID (l'ID del tuo progettoGoogle Cloud ) e Service in profiler.Config, poiché non possono essere derivati da un ambiente locale. Non è necessario impostare ServiceVersion.

Se utilizzi l'ambiente standard di App Engine, consulta la sezione Migrazione dell'app a Go 1.11 per informazioni dettagliate sulle modifiche che potresti dover apportare alla tua applicazione. Inoltre, devi utilizzare Google Cloud CLI versione 226.0.0 o successive. Per aggiornare Google Cloud CLI, esegui questo comando:

gcloud components update

Per eseguire l'applicazione:

  1. Aggiorna le dipendenze:

    go get cloud.google.com/go/profiler
    
  2. Esegui il deployment dell'applicazione nell'ambiente flessibile di App Engine o nell'ambiente standard di App Engine:

    gcloud app deploy [DEPLOYMENT]
    

    dove DEPLOYMENT è il percorso del file di configurazione. Ad esempio, DEPLOYMENT potrebbe essere main/app.yaml.

Analisi dei dati

Dopo che Profiler ha raccolto i dati, puoi visualizzarli e analizzarli utilizzando l'interfaccia Profiler.

Nella console Google Cloud , vai alla pagina Profiler:

Vai a Profiler

Puoi trovare questa pagina anche utilizzando la barra di ricerca.

Argomenti del nome e della versione del servizio

Quando carichi l'agente Profiler, specifichi un argomento service-name e un argomento service-version facoltativo per configurarlo.

Il nome del servizio consente a Profiler di raccogliere dati di profilazione per tutte le repliche del servizio. Il servizio di profilazione garantisce una velocità di raccolta di un profilo al minuto, in media, per ogni nome di servizio in ogni combinazione di versioni e zone del servizio.

Ad esempio, se hai un servizio con due versioni in esecuzione su repliche in tre zone, il profiler creerà una media di 6 profili al minuto per quel servizio.

Se utilizzi nomi di servizio diversi per le repliche, il servizio verrà profilato più spesso del necessario, con un overhead corrispondentemente più elevato.

Quando selezioni un nome servizio:

  • Scegli un nome che rappresenti chiaramente il servizio nell'architettura dell'applicazione. La scelta del nome del servizio è meno importante se esegui un solo servizio o applicazione. È più importante se la tua applicazione viene eseguita come un insieme di microservizi, ad esempio.

  • Assicurati di non utilizzare valori specifici del processo, come un ID processo, nella stringa service-name.

  • La stringa service-name deve corrispondere a questa espressione regolare:

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

Una buona linea guida è utilizzare una stringa statica come imageproc-service come nome del servizio.

La versione del servizio è facoltativa. Se specifichi la versione del servizio, Profiler può aggregare le informazioni di profilazione da più istanze e visualizzarle correttamente. Può essere utilizzato per contrassegnare le diverse versioni dei tuoi servizi durante la loro implementazione. L'interfaccia utente di Profiler ti consente di filtrare i dati in base alla versione del servizio, in modo da confrontare il rendimento delle versioni precedenti e più recenti del codice.

Il valore dell'argomento service-version è una stringa in formato libero, ma i valori per questo argomento in genere assomigliano a numeri di versione, ad esempio, 1.0.0 o 2.1.2.

Logging dell'agente

L'agente di profilazione può segnalare informazioni di debug nei suoi log. Per impostazione predefinita, la registrazione dell'agente è disattivata.

Per attivare la registrazione dell'agente, imposta l'opzione DebugLogging su true all'avvio dell'agente:

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

Risoluzione dei problemi

Questa sezione elenca i problemi specifici della profilazione delle applicazioni Go. Per assistenza per problemi comuni, consulta la sezione Risoluzione dei problemi.

Comportamento Causa Soluzione
I profili del tempo di CPU non vengono raccolti per le applicazioni create con -buildmode=c-archive. Vengono raccolti profili di heap, contesa e thread. Problema di GitHub Per impostazione predefinita, la profilazione della CPU non è attivata per le applicazioni Go quando il flag -buildmode è c-archive o c-shared. Aggiungi una chiamata a
signal.Notify(make(
chan os.Signal), syscall.SIGPROF)
prima di chiamare profiler.Start.
Risposta al problema di GitHub.

Esecuzione con Linux Alpine

L'agente di profilazione Go per Linux Alpine è supportato solo per le configurazioni Google Kubernetes Engine.

Errore di autenticazione

Se utilizzi immagini Docker eseguite con Linux Alpine (ad esempio golang:alpine o semplicemente alpine), potresti visualizzare il seguente errore di autenticazione:

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

Tieni presente che per visualizzare l'errore devi aver attivato la registrazione dell'agente. Per impostazione predefinita, l'agente per Go non genera alcun messaggio di log.

L'errore indica che le immagini Docker con Linux Alpine non hanno i certificati SSL root installati per impostazione predefinita. Questi certificati sono necessari perché l'agente di profilazione comunichi con l'API Profiler. Per risolvere questo errore, aggiungi il seguente comando apk al Dockerfile:

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

Dopodiché, devi ricompilare e ridistribuire l'applicazione.

Passaggi successivi