Profilazione delle applicazioni Go

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

Tipi di profilo per Go:

  • Tempo CPU
  • Heap
  • Heap allocato
  • Conflitto (disattiva mutex)
  • Thread (goroutine Go)

Versioni del linguaggio Go supportate:

Versioni dell'agente di profilazione supportate:

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

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 sulla configurazione specifiche per i kernel Linux Alpine, consulta Esecuzione su Linux Alpine.

Ambienti supportati:

Attivazione dell'API Profiler

Prima di utilizzare l'agente di profilazione, assicurati che l'API Profiler di base sia abilitata. Puoi controllare lo stato dell'API e abilitare e, se necessario, utilizzando Google Cloud CLI 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, significa che l'API è già abilitata. In caso contrario, fai clic sul pulsante Attiva.

Utilizzo di Cloud Profiler

In tutti gli ambienti supportati, puoi utilizzare il Profiler importando il pacchetto nell'applicazione e inizializzandolo il prima possibile.

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

Per ulteriori informazioni sull'API Profiler, incluse tutte le di configurazione, consulta le documenti relativi all'API pubblica.

Compute Engine

Per Compute Engine, in profiler.Config imposta Service con un del servizio da profilare e, facoltativamente, impostare 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 script di build o 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 profilo 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 compilazione 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 al codice sono quasi identiche a quelle per Compute Engine e GKE. C'è una sola eccezione. In entrambi gli ambienti App Engine, i parametri Service e ServiceVersion vengono ricavati 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 ProjectID (l'ID del progetto Google Cloud) e i parametri 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 Eseguire la migrazione dell'app a Go 1.11 per avere informazioni dettagliate su come le modifiche che potresti dover apportare alla tua applicazione. Inoltre, devi utilizzare la versione 226.0.0 o successive di Google Cloud CLI. Per aggiornare Google Cloud CLI, esegui il seguente 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 oppure l'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 visualizzare e analizzare questi dati 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 per nome e versione del servizio

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

Il nome del servizio consente a Profiler di raccogliere i dati di profilazione per tutte le repliche del servizio. Il servizio di profilazione garantisce un tasso di raccolta di un profilo al minuto, in media, per ogni nome di servizio in tutte le versioni e le zone dei servizi combinati.

Ad esempio, se hai un servizio con due versioni in esecuzione di 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 essere profilati più spesso del necessario, con un overhead di conseguenza più elevato.

Quando selezioni il nome di un servizio:

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

  • Assicurati di non utilizzare valori specifici per il processo, ad esempio un ID processo, nella stringa service-name.

  • La stringa del nome del servizio deve corrispondere a questa espressione regolare:

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

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

La versione del servizio è facoltativa. Se specifichi la versione del servizio, Profiler può aggregare le informazioni di profilazione da più le istanze VM e visualizzarle correttamente. Può essere utilizzato per contrassegnare versioni diverse degli tuoi servizi durante il loro dispiegamento. La UI di Profiler ti consente filtrare i dati in base alla versione del servizio; In questo modo, puoi confrontare il rendimento delle versioni più vecchie e più recenti del codice.

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

Logging agente

L'agente di profilazione può segnalare le informazioni di debug nei propri log. Per impostazione predefinita, il logging degli agenti è disabilitato.

Per abilitare il logging 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 per il profiling delle applicazioni Go. Consulta la sezione Risoluzione dei problemi. per ricevere assistenza in merito a problemi comuni.

Comportamento Causa Soluzione
I profili di tempo della CPU non vengono raccolti per le applicazioni create con -buildmode=c-archive. Vengono raccolti i profili di heap, contesa e thread. Problema GitHub Per impostazione predefinita, il profiling della CPU non è abilitato per le applicazioni Go quando il -buildmode flag è 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 su GitHub.

Esecuzione con Linux Alpine

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

Errore di autenticazione

Se utilizzi immagini Docker eseguite con Linux alpino (ad es. golang:alpine o solo alpine), potrebbe essere visualizzato 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 avere abilitato il logging dell'agente. Per impostazione predefinita, l'agente per Go non genera messaggi di log.

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

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

Devi quindi ricreare la build ed eseguire nuovamente il deployment dell'applicazione.

Passaggi successivi